我想在MASM615中重写一个给我的程序。我只是打算使用“USES”指令,这样我就不必在堆栈中进行所有的推送和弹出。这将明显改变过程中引用的一些地址,因为它们引用堆栈指针(esp)。我以为我正确地实现了它,但程序依赖于我。该过程应该输出一个直接写在代码流中的字符串,然后跳过字符串,这样CPU就不会因为尝试将字符串作为代码执行而产生错误。以下是我给予的程序:
WritePrompt PROC
push ebp
mov ebp, esp ; set up the ebp pointer
push esi ; save used reg
push eax ; save used reg
mov esi, [ebp+4] ; use ret.addr. as string pointer
L1: cmp BYTE PTR [esi], 0 ; check for the end of string
jz L2 ; jump if the string is over
mov al, [esi] ; get the next string character
call WriteChar ; ... and output it
inc esi ; increment the string pointer
jmp L1
L2: inc esi ; adjust the string pointer
mov [ebp+4], esi ; modify the return address
pop eax ; restore all used regs and exit
pop esi
pop ebp
ret
WritePrompt ENDP
这就是我给出的,下面是我的简化重写,使用USES指令跳过堆栈推送和弹出:
outStr PROC USES eax ebp esi
mov ebp, esp
mov esi, [ebp]
L1:
cmp BYTE PTR [esi], 0
jz L2
mov al, [esi]
call WriteChar
inc esi
jmp L1
L2:
inc esi
mov [ebp], esi
ret
outStr ENDP
此过程在调用时会导致程序挂起。为什么?它出什么问题了?我觉得我认为推动和弹出会带来任何变化。
编辑:添加“call dumpregs”几个地方进行调试后,我发现崩溃程序的行是“cmp BYTE PTR [esi],0”,这让我觉得我还没有得到指向字符串的指针正确地从堆栈。使用“mov esi,[ebp + 4]”似乎至少让我更远,但是它立即跳到了L2。
EDIT2:
我发现了问题。似乎我正在使用的文档非常不清楚USES指令的作用。它将所有“Used”寄存器推送到堆栈,然后弹出它们,就像没有USES指令那样。因此,我需要使用的命令是:
mov ebp, esp
add ebp, 12
mov esi, [ebp]
由于我甚至无法回答我自己的问题,我想我必须把它放在这里。这个问题已经结束。不管怎样,谢谢!
答案 0 :(得分:0)
对“使用”指令的误解。需要使用代码来补偿压入堆栈的寄存器。
mov ebp, esp
add ebp, 12
mov esi, [ebp]