帮忙解释下这几句汇编代码,各位大虾
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的整数倍.
应该是对齐.