【发布时间】:2021-10-14 16:56:07
【问题描述】:
我一直在尝试在循环中获取 2 个数字相乘的结果,但出现此错误:无效的内存引用 (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;
【问题讨论】:
-
可能不是您崩溃的原因,但是您的变量有很多字节和字访问混合,这可能会在修复崩溃后给您错误的答案。例如
num1是一个字(两个字节),但由于al是一个字节寄存器,mov al, [num1]只加载该字的低字节。我建议检查对变量的所有引用以了解正确的操作数大小。 -
convert_values最后有一个ret,但它没有被call调用,所以这将跳转到堆栈外的一个随机地址,并且可能会出现段错误。跟踪控制流向何处,并确保它在您的退出系统调用(当前无法访问)时结束。
标签: nasm