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;
我一直试图在一个循环中获得两个数字相乘的结果,但我得到了这个错误:无效的内存引用(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;