我正在嘗試使用 Borland Turbo Assembler 5(據我所知類似于 MASM 語法)為 MS-DOS 顯示一個陣列,第一個字串會列印,但其余的不會。關于使用 8086 兼容的 MS-DOS 程式集完成此任務的最佳方法有什么建議嗎?
; 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
使用 turbo 除錯器檢查我可以看到“bx”被分配了值dos_dir但我希望它會指定 dir_array 的地址。

第一個字串在 13E:

輸出:

uj5u.com熱心網友回復:
我可以看到
bx正在分配值dos_dir但我希望它會指定dir_array的地址。
TASM 遵循 MASM 風格,其中寫入mov bx, dir_array將從記憶體中獲取一個字并將其存盤在 中BX,但mov bx, offset dir_array會將有效地址存盤在 中BX。您也可以通過 獲取有效地址lea bx, dir_array,但這會浪費一個位元組。mov - offset使用 3 個位元組 vslea使用 4 個位元組。
因為dir_array包含 5 個字,并且您向其追加了一個位元組,該等式dir_array_size equ $-dir_array會將dir_array_size設定為等于 11。這意味著回圈將運行太長時間!只需洗掉額外的位元組并將條件視為無符號,畢竟它是一個計數。
一個辦法
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
替代解決方案
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
uj5u.com熱心網友回復:
修復了代碼,使用 lea 指令加載陣列,并使用 'end1' 來標記陣列的結尾。
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/352570.html
