我正在使用 NASM 学习基本汇编,并偶然发现了两个数字的
div
中的问题。section .data
msg1 db "Enter first digit (a): ", 0
len1 equ $- msg1
msg2 db "Enter second digit (b): ", 0
len2 equ $- msg2
newLine db "",0xA
msg3 db "The division (a/b) is: ",0
len3 equ $- msg3
section .bss
num1 resb 2
num2 resb 2
res resb 1
section .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, len1
int 0x80
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, len2
int 0x80
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, len3
int 0x80
mov ax, [num1] ; Load the 16-bit value from num1
sub ax, '0'
mov eax, 0 ; Clear the upper 16 bits of eax
mov [num1], ax ; Store the result back in num1
mov bx, [num2] ; Load the 16-bit value from num2
sub bx, '0'
mov ebx, 0 ; Clear the upper 16 bits of eax
mov [num2], bx ; Store the result back in num2
mov eax, [num1]
sub eax, '0'
mov ebx, [num2]
sub ebx, '0'
mov edx, 0
div bx ; eax = quotient, edx = remainder
add ax, '0'
mov [res], ax
mov eax, 4
mov ebx, 1
mov ecx, res
mov edx, 1
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, newLine
mov edx, 1
int 0x80
mov eax, 1
int 0x80
生成的输出是
我对之前关于堆栈溢出的类似问题进行了一些研究,但无济于事,也在谷歌上进行了阅读,但无法解决问题。
请帮忙,我从昨晚就被困在这个问题上了
div
虽然num1
保留了 2 个字节,但只有第一个字节对您的计算很重要。还记得您向用户询问一个个位数号码吗?减去 '0' 会正确地将字符 ["0","9"] 转换为值 [0,9],但如果将零移入 EAX,则会立即丢失该值。解决方案是编写以下内容,无需将其存储回 num1:
mov ax, [num1] ; Load the 16-bit value from num1
sub ax, '0'
mov eax, 0 ; Clear the upper 16 bits of eax
mov [num1], ax ; Store the result back in num1
movzx eax, byte [num1]
sub eax, '0'
与上面相同,但将结果保留在 EBX 中
mov bx, [num2] ; Load the 16-bit value from num2
sub bx, '0'
mov ebx, 0 ; Clear the upper 16 bits of eax
mov [num2], bx ; Store the result back in num2
这里您正在读取 4 个字节,而您只存储了 2 个字节。另外,您又错误地减去了“0”。转换之前已经完成了!这部分可以删除。
mov eax, [num1]
sub eax, '0'
与EAX类似,您也可以删除这部分。
mov ebx, [num2]
sub ebx, '0'
从你的评论来看,你似乎想要双字大小的除法,但是你需要写res。由于mov edx, 0 div bx ; eax = quotient, edx = remainder add ax, '0' mov [res], ax
变量仅保留 1 个字节,因此您永远不应该在其中写入 2 个字节。
大家一起:div ebx