NASM 程序集 - 在循环中获取两个数相乘的结果

NASM Assembly - Get the Result of Multiplying Two Numbers in a Loop

我一直试图在一个循环中获得两个数字相乘的结果,但我得到了这个错误:无效的内存引用(SIGSEGV) 我不知道我做错了什么,一些修复它的建议


;nasm 2.13.02           

section .bss
    result:     resb 2
    num1:       resb 2
    num2:       resb 2
    quotient:   resb 2
    remainder:  resb 2

section .text
    global _start

_start:
    
    ; setup registers
    ; mul -> AX = (AL * BL = AH AL)  The product is in AX. 
                                    ;High-order 8 bits of the product is stored in AH 
                                    ;and the low-order 8 bits are stored in AL.
    mov [num1], word 0x2A     ;store 42 in num1
    mov [num2], word 0x2B     ;store 43 in num2 (42*43=1806)

    mov al, [num1]
    mov bl, [num2]
    mul bl
    
    mov [result], ax
    
    ;call convert_values
    
    ;----------------------------------
    ; divide by ten
    ; div -> AX = (AX(dividendo) / BL(divisor) = AL (Quotient) AH (Remainder))  
                 ;The dividend is assumed to be in the AX register (16 bits). 
                 ;After division, the quotient goes to the AL register and 
                 ;the remainder goes to the AH register. 

    convert_values:
        xor  ax, ax          ; limpiamos el registro AX = 0
        mov  ax, [result]    
        mov  bl, 10          ; 10
        div  bl              ; divide by 10

        mov  [quotient], al  ; save the Quotient 
                
        call print_char      ;print the latest character
       
        mov ax, [quotient]
        mov [result], ax     ;move new number into result                
        
        or  ax,ax            ;set flags based on ax value
        
        jnz  convert_values  ;while ax != 0 continue process
        ret
    
    ; print a character
    print_char:
        mov [remainder], ah        ; gets the Remainder
        add [remainder], word '0'
        mov eax,4                  ; The system call for write (sys_write)
        mov ebx,1                  ; File descriptor 1 - standard output
        mov ecx,remainder          ; Put the offset of remainder in ecx
        mov edx,1                  ; is a constant, so we don't need to say
        int 80h                    ; Call the kernel
        ret
    ;------------------------------------------------
    
    mov eax,1            ; The system call for exit (sys_exit)
    mov ebx,0            ; Exit with return code of 0 (no error)
    int 80h;

这是一个更新,我修复了它。 :)


;nasm 2.13.02           

section .bss
    result:     resb 2
    num1:       resb 2
    num2:       resb 2
    quotient:   resb 2
    remainder:  resb 2

section .text
    global _start

_start:
    
    ; setup registers
    ; mul -> AX = (AX * BX = DX BX)  
                                    ;The multiplicand should be in the AX register, 
                                    ;and the multiplier is a word in memory or another register. 
                                    ;For example, for an instruction like MUL DX, 
                                    ;you must store the multiplier in DX and the multiplicand in AX.

                                    ;The resultant product is a doubleword, which will need 
                                    ;two registers. The high-order (leftmost) portion gets stored 
                                    ;in DX and the lower-order (rightmost) portion gets stored 
                                    ;in AX.
    
    mov [num1], word 0x2A     ;store 42 in eax
    mov [num2], word 0x2B     ;store 43 in edx (42*43=1806)

    mov ax, [num1]
    mov bx, [num2]
    mul bx
    
    mov [result], ax
    
    call convert_values
    
    ;----------------------------------
    ; divide by ten
    ; div -> AX = (AX(dividendo) / BL(divisor) = AL (Quotient) AH (Remainder))  
                 ;The dividend is assumed to be in the AX register (16 bits). 
                 ;After division, the quotient goes to the AL register and 
                 ;the remainder goes to the AH register. 
    convert_values:
        xor  ax, ax           ; clears AX register to `0`
        mov  ax, [result]    
        mov  bl, 10           ; 10
        div  bl               ; divide por 10

        mov  [quotient], al   ; save the Quotient 
                
        call print_char       ;print the latest character
       
        mov  ax, [quotient]   ;move `Quotient` to AX register
        test ax,ax            ;Compares if AX register is equal to `0`
        jz   exit;            ;if flag `ZF` is equal to `1` jump to `exit` label
        
        mov [result], ax      ;moves data from AX register to `result`            
        
        cmp ax,0              ;set flags based on ax value
        
        jnz  convert_values  ;while al != 0 continue process
        ret
    
    ; print a character
    print_char:
        mov [remainder], ah        ; gets the Remainder
        add [remainder], word '0'
        mov eax,4                  ; The system call for write (sys_write)
        mov ebx,1                  ; File descriptor 1 - standard output
        mov ecx,remainder          ; Put the offset of hello in ecx
        mov edx,1                  ; is a constant, so we don't need to say
        int 80h                    ; Call the kernel
        ret
    ;---------------------------------------------
    exit:
        mov eax,1            ; The system call for exit (sys_exit)
        mov ebx,0            ; Exit with return code of 0 (no error)
        int 80h;