000003b0 <_start>:
3b0: 31 ed xor %ebp,%ebp
3b2: 5e pop %esi
3b3: 89 e1 mov %esp,%ecx
3b5: 83 e4 f0 and $0xfffffff0,%esp
3b8: 50 push %eax
3b9: 54 push %esp
3ba: 52 push %edx
3bb: e8 22 00 00 00 call 3e2 <_start+0x32>
3c0: 81 c3 1c 1c 00 00 add $0x1c1c,%ebx
3c6: 8d 83 94 e5 ff ff lea -0x1a6c(%ebx),%eax
3cc: 50 push %eax
3cd: 8d 83 34 e5 ff ff lea -0x1acc(%ebx),%eax
3d3: 50 push %eax
3d4: 51 push %ecx
3d5: 56 push %esi
3d6: ff b3 1c 00 00 00 pushl 0x1c(%ebx)
3dc: e8 af ff ff ff call 390 <__libc_start_main@plt>
3e1: f4 hlt
3e2: 8b 1c 24 mov (%esp),%ebx
3e5: c3 ret
3e6: 66 90 xchg %ax,%ax
3e8: 66 90 xchg %ax,%ax
3ea: 66 90 xchg %ax,%ax
3ec: 66 90 xchg %ax,%ax
3ee: 66 90 xchg %ax,%ax
嘿,伙计们,请帮我理解addr 3b8之后的代码段。我可以猜测它在做什么,但不是很具体。
顺便说一句,如果你们有什么线索教我如何弄清楚Linux在特定代码上的调用系统的实现,请告诉我。谢谢。
在检查了ABI文档之后,仍然不太明白为什么它会跳到3e2,因为似乎他们什么也没做,只是跳了回来。
答案 0 :(得分:1)
查看i386 System V ABI文档。 (https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI)。它还详细记录了函数调用约定。 (它变得很激烈,有时更容易看一下GCC -O2
如何按值编译arg-pass或返回结构。例如,在https://godbolt.org/上)
它指定进入_start
时的用户空间堆栈布局。例如ESP指向argc
,并且argv[]
高于该值(数组内容,而不是指针)。上方envp[]
。还要注意,在动态链接的可执行文件中,_start
从动态链接器自己的启动代码中跳转到。那就是atexit指针的来源。
还要注意,这是一个PIE可执行文件,因此它将call 3e2
的PC相对寻址的返回地址存储在EBX中。