【发布时间】:2015-09-27 06:48:55
【问题描述】:
我在 Visual Studio 2010 的 x86 程序集 (MASM) 中调用了一个过程。 它所做的只是获取存储在 ax 寄存器中的以 10 为基数的数字并将其转换为二进制字符串(例如 10100b)。我遇到的问题是,每当 ax 假设等于 1 时,它反而会换行并等于某个大数字。
.code
main proc
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
lea esi, binResult ; convert result to string (binary notation)
mov ax, [result]
mov bx, 2
call Convert2Bin
lea esi, binResult ; test
call PrintString
EndofProgram:
invoke ExitProcess, 0
main endp
Convert2Bin proc ; Define procedure
pushad ; save registers
pushfd ; save flags
divide_Convert2Bin:
cmp eax, 1
je addOne_ThenExit
cmp eax, 0
je addZero_ThenExit
div ebx
cmp edx, 1
je addOne_ThenLoop
cmp edx, 0
je addZero_ThenLoop
addOne_ThenLoop:
mov byte ptr [esi], '1'
inc esi
jmp divide_Convert2Bin
addZero_ThenLoop:
mov byte ptr [esi], '0'
inc esi
jmp divide_Convert2Bin
addOne_ThenExit:
mov byte ptr [esi], '1'
inc esi
jmp done_Convert2Bin
addZero_ThenExit:
mov byte ptr [esi], '0'
inc esi
jmp done_Convert2Bin
done_Convert2Bin:
mov byte ptr [esi], 'b'
popfd ; restore flags
popad ; restore registers
ret ; return to caller
【问题讨论】:
-
pusha/popaand` 和pushf/popf都相当慢。在 asm 中编写时,您可以在每个函数的基础上构建自己的 ABI,但是保存/恢复 everything 是一个糟糕的选择。标准 ABI 不保留标志,并且有一些调用者保存的寄存器,可以在函数中使用而无需保存。您只需要保存/恢复 ABI 指定为被调用者保存的寄存器。