比较值时出现分段错误
我是汇编新手,遇到了一个我不知道如何调试的问题。我正在编写一个非常简单的程序,它接受一个命令行参数,然后输出参数的因子。目的是熟悉决策和循环。到目前为止,我已经设法将它们整合在一起,并且它适用于偶数,但不适用于奇数。此外,它可能会为偶数产生正确的结果,但在最后一次检查后仍然会出现段错误。比较值时出现分段错误
section .bss
input: resb 100
count: resb 100
main:
mov ecx,[esp+8] ;point to command line arguement
mov eax,[ecx+4] ;extract second element
push dword eax ;segfaults without dword.
call atoi ;convert the ascii from cmd line into integer.
add esp,4
mov dword [input],eax ;copy original
xor edx, edx ;zero out edx to prevent division error. [2]
mov ebx,2
div ebx ;divide eax by ebx. quotient stored in eax, remainder stored in edx.
mov [count],eax ;make a copy of the original argument/2, no number larger can be a factor.
jmp checkAgain
ret
;strFormat db `Count: %d, Quotient: %d, Remainder: %d, Input: %d, EBX: %d\n`,0
true:
push ebx
push dword [input]
push edx
push eax
push dword [count]
push strFormat
call printf
add esp,16
cmp dword [count],0
jg checkAgain
ret
checkAgain:
xor edx,edx
mov eax,[input]
mov ebx,[count]
div ebx
dec dword [count]
cmp edx,0
je true
mov ecx,dword [count]
cmp ecx,0 ;this is where I expect the program to end, but it crashes.
jg checkAgain
ret
大会对我来说很难绕过我的脑海;我有很多东西需要学习,所以我很欣赏任何反馈。
分段故障是由add esp,16
造成的。您将6个dword(= 24个字节)推入堆栈,因此必须在call printf
与add esp,24
之后清除堆栈。
您的代码不可编译。这一次对我的作品:
; Name: spagfac.asm
; Assemble: nasm -felf32 spagfac.asm
; Link: gcc -m32 -o spagfac spagfac.o
; Run: ./spagfac 60
global main
extern atoi, printf
section .bss
input: resb 100
count: resb 100
section .data
strFormat db `Count: %d, Quotient: %d, Remainder: %d, Input: %d, EBX: %d\n`,0
section .text
main:
mov ecx,[esp+8] ;point to command line arguement
mov eax,[ecx+4] ;extract second element
push dword eax ;segfaults without dword.
call atoi ;convert the ascii from cmd line into integer.
add esp,4
mov dword [input],eax ;copy original
xor edx, edx ;zero out edx to prevent division error. [2]
mov ebx,2
div ebx ;divide eax by ebx. quotient stored in eax, remainder stored in edx.
mov [count],eax ;make a copy of the original argument/2, no number larger can be a factor.
jmp checkAgain
ret
true:
push ebx
push dword [input]
push edx
push eax
push dword [count]
push strFormat
call printf
add esp,24
cmp dword [count],0
jg checkAgain
ret
checkAgain:
xor edx,edx
mov eax,[input]
mov ebx,[count]
div ebx
dec dword [count]
cmp edx,0
je true
mov ecx,dword [count]
cmp ecx,0
jg checkAgain
ret
“退出”与ret
仅适用于GCC。如果使用LD,则必须使用系统调用(int 80h/fn 01h)退出。
你对此绝对正确,我确实在堆栈中有错误的移动次数,但是,即使使用此修复程序,segfault仍会发生。 – user2325881 2014-08-29 20:14:53
@ user2325881:我更正了您的代码并将其添加到了我的帖子中。也许你使用了错误的汇编器/编译器/链接器命令。 – rkhb 2014-08-29 21:07:57
我不能用你的代码产生奇数的错误结果。请添加一个数字,预期结果和实际结果。 – rkhb 2014-08-29 09:20:59
我解释得不好。它不会产生不正确的结果,它会在程序结束时发生段错误。 – user2325881 2014-08-29 20:16:16