首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

懂得Linux命令行参数在栈中的分配

2012-11-23 
理解Linux命令行参数在栈中的分配事情的起源是,我和这个博文的作者遇到了同一个问题。这个血案我就不重述了

理解Linux命令行参数在栈中的分配
事情的起源是,我和这个博文的作者遇到了同一个问题。
这个血案我就不重述了,请见这里:http://blog.chinaunix.net/uid-24774106-id-2783020.html

该博文认为,《Professional Assembly Language》里面对Linux命令行参数在栈中的分配的描述是错的。

确实,用gcc编译书中的代码,是得不到想要的结果的。但问题不是书中说错了。而是我们编译方式不对。


使用gas编译和使用gcc编译汇编有个不同的地方,就是beginning execution entry point ,gas(即as命令)要求是.global _start,而gcc要求是.global main。
为什么有这个区别呢?

事实上ld命令是可以自己指定entry point的 (ld -emain),这样,不就可以将gcc和ld as的使用统一了吗?
当然不是的。使用gcc编译,entry point指定为main的原因在于,gcc会自己加一个_start,然后在_start里调用你的main。通过下面的代码测试下就知道了。

.section .data        hello:                .asciz "Hello,world!\n".section .text.global mainmain:        push $hello        call printf        push $0        call exit


使用gcc编译
gcc gcctest.s -o gcctest.bin -g

使用gdb看结果
$ gdb gcctest.bin Reading symbols from /data/code/asm/learn/linux/gcctest.bin...done.(gdb) disass _startDump of assembler code for function _start:   0x08048360 <+0>:     xor    %ebp,%ebp   0x08048362 <+2>:     pop    %esi   0x08048363 <+3>:     mov    %esp,%ecx   0x08048365 <+5>:     and    $0xfffffff0,%esp   0x08048368 <+8>:     push   %eax   0x08048369 <+9>:     push   %esp   0x0804836a <+10>:    push   %edx   0x0804836b <+11>:    push   $0x80484a0   0x08048370 <+16>:    push   $0x8048430   0x08048375 <+21>:    push   %ecx   0x08048376 <+22>:    push   %esi   0x08048377 <+23>:    push   $0x8048414   0x0804837c <+28>:    call   0x8048350 <__libc_start_main@plt>(gdb) disass mainDump of assembler code for function main:   0x08048414 <+0>:     push   $0x804a018   0x08048419 <+5>:     call   0x8048320 <printf@plt>   0x0804841e <+10>:    push   $0x0   0x08048420 <+12>:    call   0x8048340 <exit@plt>


可以看到。gcc添加的自己的_start,做了很多其它的工作。最后,调用main时,已经将棧修改成像C语言中main接收参数时的样子了,也就是argc和argv[],envp[]。所以,原文作者测试时发现棧中的结果会是那个样子。

相同的程序,将entry改成_start,并用as汇编,ld链接,则结果就是正确的。

事实上,gcc也可以通过参数,设置不加载它自己的startfiles
gcc gcctest.s -o gcctest.bin -g -nostartfiles


-nostartfiles参数
           Do not use the standard system startup files when linking.  The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used.


至于这个startfiles倒底做了哪些工作(比如加载动态链接库),我没有细细分析。
反正结论就是,原书作者是对的,只是因为我们用了gcc编译器,这真是一个大坑。
还有个大坑是,gcc说它支持intel_syntax,事实上呢?别提啦,更别提.att_syntax noprefix了。老实的写att_syntax,每个register都加个%前缀吧。
坑爹的汇编语言啊
1 楼 zjhlht 2012-11-09   有用!收藏一下

热点排行