我正在汇编中编写一个简单的sprintf()函数。当我尝试除以$ 0xA时,我似乎无法找出为什么我的代码获得算术执行。如果我将所有内容更改为%EAX等扩展版本,则不会发生这种情况。
.data
divisor: .byte 0xA
.text
.globl sprinter
sprinter:
.
.
.
add_unsigned_decimal_number:
pushl (%ebx)
call uint_inner
jmp next_char
uint_inner:
xor %eax, %eax
xor %edx, %edx
movw 4(%esp), %dx #Move first half of the parameter into %dx
movw 6(%esp), %ax #Move second half into %ax
#################Here it crashes###################
divw divisor #Divide by 10 (0xA)
###################################################
cmpw $0x0, %ax
je return #return if equal
pushw %dx #Save the result
pushw %ax #add a parameter for the next call
call uint_inner
pop %eax #to remove the top layer
pop %eax #To extract the required layer
addb $48, %al #To make it into a number symbol
movb %al, (%ebx) #Add the number
ret
非常感谢你的帮助。 请记住,这是一个学校问题所以请尝试解释,而不仅仅是提供工作代码。
答案 0 :(得分:0)
divw
产生16位商,如果结果不合适,则会出现异常。由于除以10,如果高位字不为零,则保证有溢出。顺便说一下,divisor
应该声明为.short
。
鉴于您明确编码32位,您应该使用32位除法。在这种情况下,除数应该是.int
,你应该将被除数加到eax
。不要忘记将edx
归零,其中包含被除数的前32位。