I just wrote a code sample in C and tried disassembling it. Following is the code sample.
void start() {
开发者_开发百科 char phone[100];
strcmp(phone, "12312312313");
char name[100];
strcmp(name, "eQuiNoX");
char contact[100];
strcmp(contact, "PM twitter.com/eQuiNoX__");
}
When I disassemble the start function I get the following:-
08048414 <start>:
8048414: 55 push ebp
8048415: 89 e5 mov ebp,esp
8048417: 81 ec 58 01 00 00 sub esp,0x158
804841d: c9 leave
804841e: c3 ret
- I have not enabled any kind of optimization. Could someone explain why I get
158
subtracted from esp rather than assembly code which pushes values onto the stack and calls thestrcmp
method? Is it because it does not depend on any user input? - Also, is there any way I could generate the
extended assembly
(im not sure if thats the right term, i just wish to see the assembly code for pushing values onto the stack and the calling of the strcmp function). Is there any way I could do that? - Is this kind of behavior specific to processor architectures or gcc versions or both?
First, strcmp
is a standard library function, so gcc is free to have special knowledge about how it works. In fact, it does; it'll seldom generate a library call. You can try -fno-builtin
to disable.
Second, you're comparing to unitialized values. This is, I believe undefined behavior. So the compiler may do anything it pleases, including producing random code.
You can try the -S
option to gcc get more detailed disassembly (or, rather, lack of assembly); alternatively, if you compile with -g
(debugging), objdump -S
will display the source along with the assembled code.
Here is an example I compiled with gcc -fno-builtin -g -O0 test.c -c
and then dumped with objdump -S test.o
:
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
#include <string.h>
int main() {
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
const char foo[] = "foo";
8: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # e <main+0xe>
e: 89 45 f0 mov %eax,-0x10(%rbp)
return strcmp(foo, "bar");
11: 48 8d 45 f0 lea -0x10(%rbp),%rax
15: be 00 00 00 00 mov $0x0,%esi
1a: 48 89 c7 mov %rax,%rdi
1d: e8 00 00 00 00 callq 22 <main+0x22>
}
22: c9 leaveq
23: c3 retq
Regarding the sub esp,0x158
instruction, rather than generate a boatload of push
operations (which involve copying the operand to the stack too, not just reserving space), typically the compiler will just reserve enough space for all local variables by moving the stack pointer just once. That's what this instruction is doing. 0x158
is 344 in decimal, so it's reserving 300 bytes for the arrays and probably some extra space for compiler generated structures (or maybe to put the strcmp operands on the stack too).
Because your code has no effect in the program execution. All variables are used in function calls whose return values are discarded, thus the compiler tagged it as unused code, and felt it should remove. If you want to keep the unused code, be sure you're not using any optimisations - compile with
-O0
.See my point above.
I suspect most compilers would perform this optimisation, independent of architecture.
It seems that it really was optimized. You can try compiling with -O0 flag to ensure that no optimization is made (however I'm not sure it will work).
Or you can just return cmp results from the start function to show the compiler that you really use them:
int start() {
char phone[] = "43423432";
return strcmp(phone, "12312312313");
}
精彩评论