Assembly 比较值时出现分段错误
我是汇编新手,遇到了一个我不知道如何调试的问题。我正在编写一个非常简单的程序,它接受一个命令行参数,然后打印参数的因子。目的是熟悉决策和循环。到目前为止,我已经成功地将其全部固定在一起,它适用于偶数,但不适用于奇数。此外,它可能会为偶数生成正确的结果,但在最后一次检查后仍会遇到SEGFULTAssembly 比较值时出现分段错误,assembly,x86,segmentation-fault,nasm,32-bit,Assembly,X86,Segmentation Fault,Nasm,32 Bit,我是汇编新手,遇到了一个我不知道如何调试的问题。我正在编写一个非常简单的程序,它接受一个命令行参数,然后打印参数的因子。目的是熟悉决策和循环。到目前为止,我已经成功地将其全部固定在一起,它适用于偶数,但不适用于奇数。此外,它可能会为偶数生成正确的结果,但在最后一次检查后仍会遇到SEGFULT section .bss input: resb 100 count: resb 100 main: mo
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
对我来说,现在很难集中精力进行组装;我有很多东西要学,所以我很感激任何反馈 分段错误是由
添加esp,16
引起的。将6个DWORD(=24字节)推送到堆栈上,因此必须在使用add esp,24
调用printf后清除堆栈
你的代码不可编译。这个对我很有用:
; 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)退出。对于代码中的奇数,我不能产生错误的结果。请把你的帖子加上一个数字,一个预期结果和真实结果。我解释得很糟糕。它不会产生不正确的结果,它会在程序结束时出现错误。这一点你肯定是正确的,我确实在堆栈中有错误的移动次数,但即使有了此修复,仍然会出现错误。@user2325881:我更正了你的代码并将其添加到我的帖子中。可能您使用了错误的汇编器/编译器/链接器命令。