Segmentation fault when popping x86 stackWhat is a segmentation fault?Jumping to the next “instruction” using gdbWhat is %gs in Assemblynasm , 64 ,linux, segmentation fault core dumpedunable to read from file when user provides filename (x86 assembly program using nasm)Push/Pop segmentation fault at Assembly x86x86 memory access segmentation faultNASM on linux: Using sys_read adds extra line at the endStack push and pop in assembly language for x86 processorserror: comma, colon, decorator or end of line expected after operand
What does it mean for a program to be 32 or 64 bit?
FIFO data structure in pure C
Find the values of U, V, C based on the given relationship...useful for upcoming puzzles
Why favour the standard WP loop over iterating over (new WP_Query())->get_posts()?
Why aren't satellites disintegrated even though they orbit earth within earth's Roche Limits?
Parse a C++14 integer literal
Isn't Kirchhoff's junction law a violation of conservation of charge?
Does the Aboleth have expertise in history and perception?
pwaS eht tirsf dna tasl setterl fo hace dorw
How to safely discharge oneself
How come Arya Stark wasn't hurt by this in Game of Thrones Season 8 Episode 5?
Novel where a cube cooled below absolute zero makes a hole in reality
Why is python script running in background consuming 100 % CPU?
Greek theta instead of lower case þ (Icelandic) in TexStudio
Bash - Execute two commands and get exit status 1 if first fails
Cycling to work - 30 mile return
Bash Array of Word-Splitting Headaches
Managing heat dissipation in a magic wand
Does a windmilling propeller create more drag than a stopped propeller in an engine out scenario?
Print characters from list with a For-loop
Will this series of events work to drown the Tarrasque?
Is presenting a play showing Military charactes in a bad light a crime in the US?
Can 2 light bulbs of 120V in series be used on 230V AC?
What were the "pills" that were added to solid waste in Apollo 7?
Segmentation fault when popping x86 stack
What is a segmentation fault?Jumping to the next “instruction” using gdbWhat is %gs in Assemblynasm , 64 ,linux, segmentation fault core dumpedunable to read from file when user provides filename (x86 assembly program using nasm)Push/Pop segmentation fault at Assembly x86x86 memory access segmentation faultNASM on linux: Using sys_read adds extra line at the endStack push and pop in assembly language for x86 processorserror: comma, colon, decorator or end of line expected after operand
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I'm trying to link x86 assembly and C.
My C program:
extern int plus_10(int);
# include <stdio.h>
int main()
int x = plus_10(40);
printf("%dn", x);
return 0;
My assembly program:
[bits 32]
section .text
global plus_10
plus_10:
pop edx
mov eax, 10
add eax, edx
ret
I compile and link the two as follows:
gcc -c prog.c -o prog_c.o -m32
nasm -f elf32 prog.asm -o prog_asm.o
gcc prog_c.o prog_asm.o -m32
However, when I run the resulting file, I get a segmentation fault.
But when I replace
pop edx
with
mov edx, [esp+4]
the program works fine. Can someone please explain why this happens?
c assembly x86
|
show 1 more comment
I'm trying to link x86 assembly and C.
My C program:
extern int plus_10(int);
# include <stdio.h>
int main()
int x = plus_10(40);
printf("%dn", x);
return 0;
My assembly program:
[bits 32]
section .text
global plus_10
plus_10:
pop edx
mov eax, 10
add eax, edx
ret
I compile and link the two as follows:
gcc -c prog.c -o prog_c.o -m32
nasm -f elf32 prog.asm -o prog_asm.o
gcc prog_c.o prog_asm.o -m32
However, when I run the resulting file, I get a segmentation fault.
But when I replace
pop edx
with
mov edx, [esp+4]
the program works fine. Can someone please explain why this happens?
c assembly x86
1
pop edx
moves the stack pointer,mov edx, [esp+4]
doesn't. Normally in C it's up to the caller to clean the stack.
– Jabberwocky
May 13 at 13:52
Well asked question. +1
– fuz
May 13 at 13:52
@Jabberwocky But why would that cause a segmentation fault? The stack is common for both functions, right?
– Susmit Agrawal
May 13 at 13:53
2
Because you popped the return address not the argument. You can't use pop like this.
– R..
May 13 at 13:55
11
@SusmitAgrawal because the return address is on the stack. Yourpop edx
actually pops the return adress from the stack and when theret
is executed the processor jumps to whatever address is on the stack
– Jabberwocky
May 13 at 13:55
|
show 1 more comment
I'm trying to link x86 assembly and C.
My C program:
extern int plus_10(int);
# include <stdio.h>
int main()
int x = plus_10(40);
printf("%dn", x);
return 0;
My assembly program:
[bits 32]
section .text
global plus_10
plus_10:
pop edx
mov eax, 10
add eax, edx
ret
I compile and link the two as follows:
gcc -c prog.c -o prog_c.o -m32
nasm -f elf32 prog.asm -o prog_asm.o
gcc prog_c.o prog_asm.o -m32
However, when I run the resulting file, I get a segmentation fault.
But when I replace
pop edx
with
mov edx, [esp+4]
the program works fine. Can someone please explain why this happens?
c assembly x86
I'm trying to link x86 assembly and C.
My C program:
extern int plus_10(int);
# include <stdio.h>
int main()
int x = plus_10(40);
printf("%dn", x);
return 0;
My assembly program:
[bits 32]
section .text
global plus_10
plus_10:
pop edx
mov eax, 10
add eax, edx
ret
I compile and link the two as follows:
gcc -c prog.c -o prog_c.o -m32
nasm -f elf32 prog.asm -o prog_asm.o
gcc prog_c.o prog_asm.o -m32
However, when I run the resulting file, I get a segmentation fault.
But when I replace
pop edx
with
mov edx, [esp+4]
the program works fine. Can someone please explain why this happens?
c assembly x86
c assembly x86
asked May 13 at 13:51
Susmit AgrawalSusmit Agrawal
1,199718
1,199718
1
pop edx
moves the stack pointer,mov edx, [esp+4]
doesn't. Normally in C it's up to the caller to clean the stack.
– Jabberwocky
May 13 at 13:52
Well asked question. +1
– fuz
May 13 at 13:52
@Jabberwocky But why would that cause a segmentation fault? The stack is common for both functions, right?
– Susmit Agrawal
May 13 at 13:53
2
Because you popped the return address not the argument. You can't use pop like this.
– R..
May 13 at 13:55
11
@SusmitAgrawal because the return address is on the stack. Yourpop edx
actually pops the return adress from the stack and when theret
is executed the processor jumps to whatever address is on the stack
– Jabberwocky
May 13 at 13:55
|
show 1 more comment
1
pop edx
moves the stack pointer,mov edx, [esp+4]
doesn't. Normally in C it's up to the caller to clean the stack.
– Jabberwocky
May 13 at 13:52
Well asked question. +1
– fuz
May 13 at 13:52
@Jabberwocky But why would that cause a segmentation fault? The stack is common for both functions, right?
– Susmit Agrawal
May 13 at 13:53
2
Because you popped the return address not the argument. You can't use pop like this.
– R..
May 13 at 13:55
11
@SusmitAgrawal because the return address is on the stack. Yourpop edx
actually pops the return adress from the stack and when theret
is executed the processor jumps to whatever address is on the stack
– Jabberwocky
May 13 at 13:55
1
1
pop edx
moves the stack pointer, mov edx, [esp+4]
doesn't. Normally in C it's up to the caller to clean the stack.– Jabberwocky
May 13 at 13:52
pop edx
moves the stack pointer, mov edx, [esp+4]
doesn't. Normally in C it's up to the caller to clean the stack.– Jabberwocky
May 13 at 13:52
Well asked question. +1
– fuz
May 13 at 13:52
Well asked question. +1
– fuz
May 13 at 13:52
@Jabberwocky But why would that cause a segmentation fault? The stack is common for both functions, right?
– Susmit Agrawal
May 13 at 13:53
@Jabberwocky But why would that cause a segmentation fault? The stack is common for both functions, right?
– Susmit Agrawal
May 13 at 13:53
2
2
Because you popped the return address not the argument. You can't use pop like this.
– R..
May 13 at 13:55
Because you popped the return address not the argument. You can't use pop like this.
– R..
May 13 at 13:55
11
11
@SusmitAgrawal because the return address is on the stack. Your
pop edx
actually pops the return adress from the stack and when the ret
is executed the processor jumps to whatever address is on the stack– Jabberwocky
May 13 at 13:55
@SusmitAgrawal because the return address is on the stack. Your
pop edx
actually pops the return adress from the stack and when the ret
is executed the processor jumps to whatever address is on the stack– Jabberwocky
May 13 at 13:55
|
show 1 more comment
1 Answer
1
active
oldest
votes
This is a possible assembly code of int x = plus_10(40);
push 40 ; push argument
call plus_10 ; call function
retadd: add esp, 4 ; clean up stack (dummy pop)
; result of the function call is in EAX, per the calling convention
; if compiled without optimization, the caller might just store it:
mov DWORD PTR [ebp-x], eax ; store return value
; (in eax) in x
Now when you call plus_10
, the address retadd
is pushed on the stack by the call
instruction. It's effectively a push
+jmp
, and ret
is effectively pop eip
.
So your stack looks like this in the plus_10
function:
| ... |
+--------+
| 40 | <- ESP+4 points here (the function argument)
+--------+
| retadd | <- ESP points here
+--------+
ESP
points to a memory location that contains the return address.
Now if you use pop edx
the return address goes into edx
and the stack looks like this:
| ... |
+--------+
| 40 | <- ESP points here
+--------+
Now if you execute ret
at this point, the program will actually jump to address 40 and most likely segfault or behave in some other unpredictable way.
The actual assembly code generated by the compiler may be different, but this illustrates the problem.
BTW, a more efficient way to write your function is this: it's what most compilers would do with optimization enabled, for a non-inline version of this tiny function.
global plus_10
plus_10:
mov eax, [esp+4] ; retval = first arg
add eax, 10 ; retval += 10
ret
This is smaller and slightly more efficient than
mov eax, 10
add eax, [esp+4] ; decode to a load + add.
ret
3
The cdecl calling convention will expect the value to get returned through eax though. So you can't just write the asm function the way you like, it has to be compatible with the compiler-generated C.
– Lundin
May 13 at 14:12
1
@Lundin apparently his platform uses the cdecl convention. I also wrote it's possible assembly code, so depending on the platform it might be somewhat different. Edited and clarified. Thanks.
– Jabberwocky
May 13 at 14:14
This really clears things up!
– Susmit Agrawal
May 13 at 14:14
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56113827%2fsegmentation-fault-when-popping-x86-stack%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is a possible assembly code of int x = plus_10(40);
push 40 ; push argument
call plus_10 ; call function
retadd: add esp, 4 ; clean up stack (dummy pop)
; result of the function call is in EAX, per the calling convention
; if compiled without optimization, the caller might just store it:
mov DWORD PTR [ebp-x], eax ; store return value
; (in eax) in x
Now when you call plus_10
, the address retadd
is pushed on the stack by the call
instruction. It's effectively a push
+jmp
, and ret
is effectively pop eip
.
So your stack looks like this in the plus_10
function:
| ... |
+--------+
| 40 | <- ESP+4 points here (the function argument)
+--------+
| retadd | <- ESP points here
+--------+
ESP
points to a memory location that contains the return address.
Now if you use pop edx
the return address goes into edx
and the stack looks like this:
| ... |
+--------+
| 40 | <- ESP points here
+--------+
Now if you execute ret
at this point, the program will actually jump to address 40 and most likely segfault or behave in some other unpredictable way.
The actual assembly code generated by the compiler may be different, but this illustrates the problem.
BTW, a more efficient way to write your function is this: it's what most compilers would do with optimization enabled, for a non-inline version of this tiny function.
global plus_10
plus_10:
mov eax, [esp+4] ; retval = first arg
add eax, 10 ; retval += 10
ret
This is smaller and slightly more efficient than
mov eax, 10
add eax, [esp+4] ; decode to a load + add.
ret
3
The cdecl calling convention will expect the value to get returned through eax though. So you can't just write the asm function the way you like, it has to be compatible with the compiler-generated C.
– Lundin
May 13 at 14:12
1
@Lundin apparently his platform uses the cdecl convention. I also wrote it's possible assembly code, so depending on the platform it might be somewhat different. Edited and clarified. Thanks.
– Jabberwocky
May 13 at 14:14
This really clears things up!
– Susmit Agrawal
May 13 at 14:14
add a comment |
This is a possible assembly code of int x = plus_10(40);
push 40 ; push argument
call plus_10 ; call function
retadd: add esp, 4 ; clean up stack (dummy pop)
; result of the function call is in EAX, per the calling convention
; if compiled without optimization, the caller might just store it:
mov DWORD PTR [ebp-x], eax ; store return value
; (in eax) in x
Now when you call plus_10
, the address retadd
is pushed on the stack by the call
instruction. It's effectively a push
+jmp
, and ret
is effectively pop eip
.
So your stack looks like this in the plus_10
function:
| ... |
+--------+
| 40 | <- ESP+4 points here (the function argument)
+--------+
| retadd | <- ESP points here
+--------+
ESP
points to a memory location that contains the return address.
Now if you use pop edx
the return address goes into edx
and the stack looks like this:
| ... |
+--------+
| 40 | <- ESP points here
+--------+
Now if you execute ret
at this point, the program will actually jump to address 40 and most likely segfault or behave in some other unpredictable way.
The actual assembly code generated by the compiler may be different, but this illustrates the problem.
BTW, a more efficient way to write your function is this: it's what most compilers would do with optimization enabled, for a non-inline version of this tiny function.
global plus_10
plus_10:
mov eax, [esp+4] ; retval = first arg
add eax, 10 ; retval += 10
ret
This is smaller and slightly more efficient than
mov eax, 10
add eax, [esp+4] ; decode to a load + add.
ret
3
The cdecl calling convention will expect the value to get returned through eax though. So you can't just write the asm function the way you like, it has to be compatible with the compiler-generated C.
– Lundin
May 13 at 14:12
1
@Lundin apparently his platform uses the cdecl convention. I also wrote it's possible assembly code, so depending on the platform it might be somewhat different. Edited and clarified. Thanks.
– Jabberwocky
May 13 at 14:14
This really clears things up!
– Susmit Agrawal
May 13 at 14:14
add a comment |
This is a possible assembly code of int x = plus_10(40);
push 40 ; push argument
call plus_10 ; call function
retadd: add esp, 4 ; clean up stack (dummy pop)
; result of the function call is in EAX, per the calling convention
; if compiled without optimization, the caller might just store it:
mov DWORD PTR [ebp-x], eax ; store return value
; (in eax) in x
Now when you call plus_10
, the address retadd
is pushed on the stack by the call
instruction. It's effectively a push
+jmp
, and ret
is effectively pop eip
.
So your stack looks like this in the plus_10
function:
| ... |
+--------+
| 40 | <- ESP+4 points here (the function argument)
+--------+
| retadd | <- ESP points here
+--------+
ESP
points to a memory location that contains the return address.
Now if you use pop edx
the return address goes into edx
and the stack looks like this:
| ... |
+--------+
| 40 | <- ESP points here
+--------+
Now if you execute ret
at this point, the program will actually jump to address 40 and most likely segfault or behave in some other unpredictable way.
The actual assembly code generated by the compiler may be different, but this illustrates the problem.
BTW, a more efficient way to write your function is this: it's what most compilers would do with optimization enabled, for a non-inline version of this tiny function.
global plus_10
plus_10:
mov eax, [esp+4] ; retval = first arg
add eax, 10 ; retval += 10
ret
This is smaller and slightly more efficient than
mov eax, 10
add eax, [esp+4] ; decode to a load + add.
ret
This is a possible assembly code of int x = plus_10(40);
push 40 ; push argument
call plus_10 ; call function
retadd: add esp, 4 ; clean up stack (dummy pop)
; result of the function call is in EAX, per the calling convention
; if compiled without optimization, the caller might just store it:
mov DWORD PTR [ebp-x], eax ; store return value
; (in eax) in x
Now when you call plus_10
, the address retadd
is pushed on the stack by the call
instruction. It's effectively a push
+jmp
, and ret
is effectively pop eip
.
So your stack looks like this in the plus_10
function:
| ... |
+--------+
| 40 | <- ESP+4 points here (the function argument)
+--------+
| retadd | <- ESP points here
+--------+
ESP
points to a memory location that contains the return address.
Now if you use pop edx
the return address goes into edx
and the stack looks like this:
| ... |
+--------+
| 40 | <- ESP points here
+--------+
Now if you execute ret
at this point, the program will actually jump to address 40 and most likely segfault or behave in some other unpredictable way.
The actual assembly code generated by the compiler may be different, but this illustrates the problem.
BTW, a more efficient way to write your function is this: it's what most compilers would do with optimization enabled, for a non-inline version of this tiny function.
global plus_10
plus_10:
mov eax, [esp+4] ; retval = first arg
add eax, 10 ; retval += 10
ret
This is smaller and slightly more efficient than
mov eax, 10
add eax, [esp+4] ; decode to a load + add.
ret
edited May 14 at 2:20
Peter Cordes
140k20214355
140k20214355
answered May 13 at 14:08
JabberwockyJabberwocky
28.9k104076
28.9k104076
3
The cdecl calling convention will expect the value to get returned through eax though. So you can't just write the asm function the way you like, it has to be compatible with the compiler-generated C.
– Lundin
May 13 at 14:12
1
@Lundin apparently his platform uses the cdecl convention. I also wrote it's possible assembly code, so depending on the platform it might be somewhat different. Edited and clarified. Thanks.
– Jabberwocky
May 13 at 14:14
This really clears things up!
– Susmit Agrawal
May 13 at 14:14
add a comment |
3
The cdecl calling convention will expect the value to get returned through eax though. So you can't just write the asm function the way you like, it has to be compatible with the compiler-generated C.
– Lundin
May 13 at 14:12
1
@Lundin apparently his platform uses the cdecl convention. I also wrote it's possible assembly code, so depending on the platform it might be somewhat different. Edited and clarified. Thanks.
– Jabberwocky
May 13 at 14:14
This really clears things up!
– Susmit Agrawal
May 13 at 14:14
3
3
The cdecl calling convention will expect the value to get returned through eax though. So you can't just write the asm function the way you like, it has to be compatible with the compiler-generated C.
– Lundin
May 13 at 14:12
The cdecl calling convention will expect the value to get returned through eax though. So you can't just write the asm function the way you like, it has to be compatible with the compiler-generated C.
– Lundin
May 13 at 14:12
1
1
@Lundin apparently his platform uses the cdecl convention. I also wrote it's possible assembly code, so depending on the platform it might be somewhat different. Edited and clarified. Thanks.
– Jabberwocky
May 13 at 14:14
@Lundin apparently his platform uses the cdecl convention. I also wrote it's possible assembly code, so depending on the platform it might be somewhat different. Edited and clarified. Thanks.
– Jabberwocky
May 13 at 14:14
This really clears things up!
– Susmit Agrawal
May 13 at 14:14
This really clears things up!
– Susmit Agrawal
May 13 at 14:14
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56113827%2fsegmentation-fault-when-popping-x86-stack%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
pop edx
moves the stack pointer,mov edx, [esp+4]
doesn't. Normally in C it's up to the caller to clean the stack.– Jabberwocky
May 13 at 13:52
Well asked question. +1
– fuz
May 13 at 13:52
@Jabberwocky But why would that cause a segmentation fault? The stack is common for both functions, right?
– Susmit Agrawal
May 13 at 13:53
2
Because you popped the return address not the argument. You can't use pop like this.
– R..
May 13 at 13:55
11
@SusmitAgrawal because the return address is on the stack. Your
pop edx
actually pops the return adress from the stack and when theret
is executed the processor jumps to whatever address is on the stack– Jabberwocky
May 13 at 13:55