给定程序的输出应为1--2--3--3--4--5--6--7--8。 但是,我一直给我1--2--3--4--4--5--6--7-8--。我需要在8点后摆脱“-”,但我不知道怎么做。有人可以帮我吗?
INCLUDE Irvine32.inc
.data
arrayb byte 1,2,3,4,5,6,7,8
space byte "--",0
.code
main PROC
mov eax,0
mov edx,offset space
mov esi,offset arrayb
mov ecx, 8
printb:
mov al, [esi]
call writedec
call writestring
inc esi
mov eax, 8
loop printb
exit
main ENDP
end main
答案 0 :(得分:4)
您的代码(特别是循环)当前执行以下操作:
<init state>
counter = 8
printb:
output number
output "--"
loop to printb
<exit>
如果在头上穿过它,很明显为什么在最后一个数字后会显示“-”。
调整代码的方式有很多,在现实世界中,进行格式化的代码时,我经常使用某种join
函数,该函数采用列表和分隔符,并产生格式化的字符串,或者手动进行格式化,我可能会在循环之前对输出“ 1”进行硬编码,将状态初始化为好像从“ 2”开始一样开始循环,并在循环中首先输出“-”,即:
<init state>
output number
advance state as if it was printed inside loop
counter = 8-1 ; one value is already out
printb:
output "--" ; the loop body starts with "--" output
output number
loop to printb
<exit>
即在您的代码中(通过一些修改“改善”了一些我不喜欢的东西:
...
mov edx,offset space
mov esi,offset arrayb
movzx eax, BYTE PTR [esi]
inc esi
call writedec
mov ecx, 8-1
printb:
call writestring
movzx eax, BYTE PTR [esi]
inc esi
call writedec
loop printb
exit
...
编辑
彼得·科德斯(Peter Cordes)通过注释使最后一个项目变成特殊情况的想法可能会在通用情况下导致更好的代码,在通用情况下,项目的数量是可变的(固定为“ 8”,您可以显示第一个元素,然后再显示7个元素)被循环)。
让我们想象一下汇编中的这种功能,在寄存器中接受参数:
; esi = byte array to output
; ecx = amount of bytes
; will modify eax, ecx, edx, esi
OutputByteArray PROC
jecxz NoItemsToOutput ; if ecx=0
dec ecx
jz OutputLastItem ; if ecx=1, display only last item
; 1 < count, so "0 < ecx" here (ecx = count-1) => do the loop
mov edx,offset space
printb: ; output number and "--" "count-1" times
movzx eax, BYTE PTR [esi]
inc esi
call writedec
call writestring
loop printb
OutputLastItem:
movzx eax, BYTE PTR [esi]
call writedec
NoItemsToOutput:
ret
ENDP