我正在尝试在x86中编写一个简单的程序(使用MASM进行编译)。 它的目的是将命令行参数写入输出(每个参数都在一个新行中)。 这是我到目前为止所提出的:
data1 segment
input db 40 dup (?) ;input
data1 ends
code1 segment
START:
mov ax,seg input
mov ds,ax
mov dx,offset input
mov di, dx
mov si, 82h
mov cl,es:[80h]
word:
mov al,es:[si]
mov ds:[di],al
inc si
inc di
cmp al,0Dh ;out of arguments? (if YES goto finish)
jz finish
cmp al,20h ;end of word? (if NO goto word)
jnz word
mov al, '$' ;line terminate
mov ds:[di], al
mov ah,09h ;write string
int 21h
xor di,di ;prepare registry for new word
call new_line
loop word
finish:
mov al, '$'
mov ds:[di], al
mov ah,09h ;write last argument
int 21h
mov ax,4ch ;end program
int 21h
new_line:
push ax
push bp
mov ax,0e0ah ;ah=0e-write char,al=0a-go to new line
int 10h
mov al,13 ;carriage return
int 10h
pop bp
pop ax
ret
code1 ends
end START
在emu8086下进行测试似乎工作正常,但在使用MASM编译后,只有10%的执行才能得到正确的结果。 任何帮助将不胜感激
答案 0 :(得分:2)
自从我查看任何汇编程序以来,已经有很长时间......大提示而不是here's your answer
你确定ES已经加载了适当的段,因为你没有初始化它吗?
请注意,通过加载内容为80H的CL,您将CL设置为命令行的LENGTH。
当你循环回WORD(不是标签的好名字,顺便说一下 - 因为它是一个关键字)你正在转移下一个字节。一切都很好 - 但你不是递减CL,命令行中的字符数。您应跳转到LOOP指令,如果未达到0,则递减CX并返回目标标签。
在执行INT 10h
之前,您已经非常小心(并且正确地)保存了BP和AX这两个寄存器是否足够?也许其他寄存器也被修改......
同样,INT 21H
- 是否有任何寄存器可以通过执行该中断后面的例程来改变?如果是这样,您应首先PUSH
他们,并在例程结束后POP
他们回来。
依靠CR = 0DH = 13结束这条线是非常有意义的。如果参数的可用空间完全填充,则会丢失此项。 CL中的字符数更重要。如果您使用LOOP
指令正确地减少CL,则您不会遇到CR(IIRC),因为它不是计数的一部分。当然,这假设CX
并未因空格的所有文件夹检查或写出行而改变...
哦,顺便说一下 - 按照这个顺序,新行是CR
,LF
或0DH,0AH。在机械终端上,这实际上是将打印头移回左侧,然后将纸张向上滚动一行。打印头非常坚固,当它们在弹簧加载的挡块上返回时会收集到大量的动量。结果是它们经常弹跳,下一行的起始字符将喷涂在打印输出的前几列上,因为打印头已经稳定,每一条新线都不可避免地使机械装置越来越不合理。事实上,将换行符作为CR LF CR并不罕见,只是为了让机械师有时间来解决。
答案 1 :(得分:1)
在开始复制参数字符串之前:
mov dx,offset input
mov di, dx
但如果有多个参数,则在打印完第一个参数后执行此操作:
xor di,di ;prepare registry for new word
那应该是mov di, dx
,除非你绝对,肯定地,100%确定input
的偏移总是为0。