1

I'm trying to display an array using Borland Turbo Assembler 5 (similar to MASM syntax as far as I know) for MS-DOS, the first string prints but remaining ones don't. Any advice on best way to accomplish this with 8086 compatible MS-DOS assembly?

    ; TEST.COM:    
    
    stdin   equ     0   ; standard input handle
stdout  equ     1   ; standard output handle
stderr  equ     2   ; standard error handle

cr      equ     0dh ; ASCII carriage return
lf      equ     0ah ; ASCII linefeed
escape  equ     1Bh ; escape
fg_black equ    escape,'[30m'
fg_red   equ    escape,'[31m'

_TEXT   segment word public 'CODE'

    org     100h

    assume  cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT

main    proc near   
        mov     bx,dir_array
        mov     ah,9
dirloop:
        lea     dx,[bx]
        int     21h
        add     bx,2
        cmp     bx,offset dir_array+dir_array_size
        jl      dirloop

        mov     ax,4C00h
        int     21h

main    endp

msg1    db  cr,lf
        db  'DOS FindFirst API Test',cr,lf

dir_array       dw dos_dir,int21_3E_dir,test_dir1,test_dir2,test_dir3
end1 db '$'
dir_array_size  equ $-dir_array
end2 db '$'
dos_dir    db 'C:\DOS',cr,lf,'$'
int21_3E_dir db "C:\DOS\INT21_3E",cr,lf,'$'
test_dir1   db "C:\DOS\INT21_3E\TEST1",cr,lf,'$'
test_dir2   db "C:\DOS\INT21_3E\TEST2",cr,lf,'$'
test_dir3   db "C:\DOS\INT21_3E\TEST3",cr,lf,'$'
test_file1   db "C:\DOS\INT21_3E\ARC.TXT",0
test_file2   db "C:\DOS\INT21_3E\RONLY.TXT",0
test_file3   db "C:\DOS\INT21_3E\SYSTEM.TXT",0
test_file4   db "C:\DOS\INT21_3E\HIDDEN.TXT",0
msg1_len equ $-msg1
_TEXT   ends

end main

Checking with turbo debugger I can see "bx" is being assigned the value dos_dir but I was hoping it would specify the address of dir_array.

enter image description here

The first string is at 13E:

enter image description here

Output:

enter image description here

2
  • Seems to me like the first time you read [bx] you're reading from beyond the end of your array, and you exit the loop before reading the first element in the array. Commented Nov 4, 2021 at 6:48
  • Updated with some more info and output from debugger Commented Nov 4, 2021 at 6:52

2 Answers 2

1

I can see bx is being assigned the value dos_dir but I was hoping it would specify the address of dir_array.

TASM follows MASM-style where writing mov bx, dir_array will fetch a word from memory and store it in BX, but mov bx, offset dir_array will store the effective address in BX. You can also obtain the effective address via lea bx, dir_array, but that would waste a byte. mov - offset use 3 bytes vs lea using 4 bytes.

Because the dir_array contains 5 words and you appended a further byte to it, the dir_array_size equ $-dir_array equate will set dir_array_size equal to 11. This means that the loop will run too long! Just drop the extra byte and also treat the conditional as unsigned, after all it's a count.

A solution

  mov  si, offset dir_array
dirloop:
  lodsw
  mov  dx, ax
  mov  ah, 09h   ; DOS.PrintString
  int  21h
  cmp  si, offset dir_array + dir_array_size
  jb   dirloop

  ...

dir_array       dw dos_dir, int21_3E_dir, test_dir1, test_dir2, test_dir3
dir_array_size  equ $-dir_array

An alternative solution

  xor  bx, bx
dirloop:
  mov  dx, dir_array[bx]
  mov  ah, 09h   ; DOS.PrintString
  int  21h
  add  bx, 2
  cmp  bx, dir_array_size
  jb   dirloop

  ...

dir_array       dw dos_dir, int21_3E_dir, test_dir1, test_dir2, test_dir3
dir_array_size  equ $-dir_array
Sign up to request clarification or add additional context in comments.

Comments

0

Fixed code, using lea instruction to load array, and an 'end1' to mark the end of array.

stdin   equ     0   ; standard input handle
stdout  equ     1   ; standard output handle
stderr  equ     2   ; standard error handle

cr      equ     0dh ; ASCII carriage return
lf      equ     0ah ; ASCII linefeed
escape  equ     1Bh ; escape
fg_black equ    escape,'[30m'
fg_red   equ    escape,'[31m'

_TEXT   segment word public 'CODE'

    org     100h

    assume  cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT

main    proc near   
        lea     bx,dir_array
        mov     ah,9
dirloop:
        mov     dx,[bx]
        int     21h
        add     bx,2
        cmp     bx,offset end1
        jl      dirloop

        mov     ax,4C00h
        int     21h

main    endp

msg1    db  cr,lf
        db  'DOS FindFirst API Test',cr,lf

dir_array       dw dos_dir,int21_3E_dir,test_dir1,test_dir2,test_dir3
end1 db '$'
dir_array_size  equ $-dir_array
end2 db '$'
dos_dir    db 'C:\DOS',cr,lf,'$'
int21_3E_dir db "C:\DOS\INT21_3E",cr,lf,'$'
test_dir1   db "C:\DOS\INT21_3E\TEST1",cr,lf,'$'
test_dir2   db "C:\DOS\INT21_3E\TEST2",cr,lf,'$'
test_dir3   db "C:\DOS\INT21_3E\TEST3",cr,lf,'$'
test_file1   db "C:\DOS\INT21_3E\ARC.TXT",0
test_file2   db "C:\DOS\INT21_3E\RONLY.TXT",0
test_file3   db "C:\DOS\INT21_3E\SYSTEM.TXT",0
test_file4   db "C:\DOS\INT21_3E\HIDDEN.TXT",0
msg1_len equ $-msg1
_TEXT   ends

end main

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.