日期:2014-05-16  浏览次数:20597 次

帮忙解释下这几句汇编代码,各位大虾
gcc编译输出后用objdump得到的
fprintf(stderr,"%d%d%d%s\n",a,b,c,p);
 80483c8: 83 ec 08 sub $0x8,%esp
 80483cb: ff 75 f0 pushl 0xfffffff0(%ebp)
 80483ce: ff 75 f4 pushl 0xfffffff4(%ebp)
 80483d1: ff 75 f8 pushl 0xfffffff8(%ebp)
 80483d4: ff 75 fc pushl 0xfffffffc(%ebp)
 80483d7: 68 d1 84 04 08 push $0x80484d1
 80483dc: ff 35 e0 95 04 08 pushl 0x80495e0
 80483e2: e8 e1 fe ff ff call 80482c8 <fprintf@plt>
 80483e7: 83 c4 20 add $0x20,%esp

弄不懂第一个sub和最后一个add有什么用,其中a,b,c为int,p为char *

帮帮忙啊,准备使用内联汇编调用fprintf函数,自己push参数,在这里卡住了

------解决方案--------------------
80483c8: 83 ec 08 sub $0x8,%esp :

在堆栈中建立自动变量;

80483e7: 83 c4 20 add $0x20,%esp:

恢复栈指针。
------解决方案--------------------
sub $0x8,%esp -- 目的使堆栈指针下移8字节,相当于两个pushl(入栈8字节).
然后将6个fprintf()参数压入堆栈,注意入栈顺序跟函数签名顺序相反,即先压入p,最后压入stderr(调用函数从栈顶读起,刚好顺序读到参数)
然后使用call中断,以调用函数fprintf@plt.
add $0x20,%esp -- 其实等人于8次pushl,将恢复调用前的堆栈指针ebp.
这里是对的,0x20=32,相当于出栈32字节.而前面正好压入32个字节.
前面压入8字节(sub $0x8,%esp )空数据,估计是fprintf@plt的约定使用,不太了解
------解决方案--------------------
这两个语句从语句面上很好解释, 就是移动栈指针.
最后的add只能是16的整数倍, 也就是0x10 0x20之类的, 前面的sub是为了和pushl的一起凑成16的整数倍.

应该是对齐.