NASM 中的 div 问题

问题描述 投票:0回答:1

我正在使用 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

生成的输出是

我对之前关于堆栈溢出的类似问题进行了一些研究,但无济于事,也在谷歌上进行了阅读,但无法解决问题。

请帮忙,我从昨晚就被困在这个问题上了

assembly x86 nasm division
1个回答
0
投票
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'


从你的评论来看,你似乎想要双字大小的除法,但是你需要写
mov edx, 0
div bx     ; eax = quotient, edx = remainder
add ax, '0'
mov [res], ax
。由于
res

变量仅保留 1 个字节,因此您永远不应该在其中写入 2 个字节。

大家一起:
div ebx

© www.soinside.com 2019 - 2024. All rights reserved.