我是装配新手,我遇到了一个我不知道如何调试的问题。我正在编写一个非常简单的程序,该程序接受命令行参数,然后打印参数的因子。目的是熟悉决策和循环。到目前为止,我设法将它们全部组合在一起,它适用于偶数,但不适用于奇数。此外,它可能会为偶数产生正确的结果,但在最后一次检查后仍然会遇到段错误。
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
我现在非常难以集思广益;我有很多东西需要学习,所以我很感激任何反馈。
答案 0 :(得分:1)
分段错误是由add esp,16
引起的。您将6个双字(= 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)退出。