问题
This is my x86 assembly code:
section .data
output db '%d',10,0
section .text
global main
extern printf
main :
xor ecx,ecx
xor eax,eax
mov eax,1
mov ecx,5
lable1:
push ecx
push eax
cmp eax,0
jg print
pop eax
pop ecx
inc eax
loop lable1
ret
print:
push eax
push output
call printf
add esp,8
ret
This program should print all numbers between 1 to 5. Why am I getting a segmentation fault after printing '1'?
回答1:
print
ends with a ret
instruction, which implies that it is something that you should call
. So jg print
should be jng skip
/ call print
/ skip:
(or just call print
, because the > 0
check seems unnecessary).call
places the return address on the stack, jg
does not.
回答2:
The reason why you keep getting faults is: You are ignoring the stack!
Your lable1
subroutine is correctly set up, but with your jg
you eject from it ignoring the stack - leaving the stack corrupt.
lable1:
push ecx
push eax
cmp eax,0
jg print
pop eax
pop ecx
inc eax
You
xor eax,eax ; EAX = 0 - breaking pipeline
mov eax,1 ; EAX = 1 - which is redundant
but because of your
cmp eax,0
jg print
in the lable1
subroutine, you jump to the print:
routine if EAX is greater than 0
(and it is in the first iteration with EAX=1) with a stack offset of -8
caused by
push ecx
push eax
in the beginning of lable1:
. The ret
ting from print:
, which cleans up the stack properly by add esp,8
at the end, will cause your program to return to the address of the first entry of the stack, which you have assigned to [ESP]=(former EAX = 1) in main:mov eax,1
.
Therefore you get a SegFault
, because you try to jump/return to the address [00000001] (=EAX=1,32bit).
来源:https://stackoverflow.com/questions/36498852/why-is-segmention-fault-while-printing