我对装配还是比较新的,我在解决我要解决的问题中最后一点装配时遇到了一些麻烦(找到esp结尾处的esp值之间的差异代码,以及保存的返回地址的位置)。根据我的理解,前5行是功能" prologue"因为它设置了基本和堆栈指针,然后通过值0xf8(248)偏离(减去?),在新堆栈的一部分之间做任何事情并将一些寄存器推到它上面。但是,我真的不明白之后会发生什么。我知道它将堆栈指针设置为不同的值但不了解堆栈指针如何在不破坏程序本身的情况下如此移动。对不起语法或技术问题,但我只是高中三年级学生,没有comp sci的背景,而且相当难以理解这一点。
foo:
pushl %ebp
mov %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
sub $0xf8, %esp
movl $0x1, (%esp)
movl $0x2, 0x4(%esp)
movl $0x3, 0x8(%esp)
movl $0x4, 0xc(%esp)
答案 0 :(得分:0)
问题在于你使自己遭受了AT& T语法的憎恶 它将英特尔汇编代码转换为格式meant for the PDP(1959年首次制造的处理器)。
在理智的语法中,本节如下所示:
foo:
push ebp
mov ebp,esp //set up a stack frame
push edi //save some registers on the stack
push esi
push ebx
sub esp, 0xf8 //push down the stack pointer to make space
//for local variables
mov dword ptr [esp],1 //local int1 = 1
mov dword ptr [esp+4],2 //local int2 = 2
mov dword ptr [esp+8],3 //local int3 = 3
mov dword ptr [esp+12],4 //local int4 = 4
If you are forced to use GAS you can restore sanity using
.intel_syntax noprefix
作为第一个伪指令。
答案 1 :(得分:0)
我有一点怀疑。问题是找到代码末尾的esp值和保存的返回地址的位置之间的差异。 我这样想:
假设x
是返回地址(ebp)
mov %esp,%ebp // basically x=esp=ebp
pushl %edi //push statement so x+4 (since stack grows towards higher memory address)
pushl %esi // now x+4+4
pushl %ebx //x+4+4+4
sub $0xf8, %esp //x+4+4+4+(0xf8-x)
代码末尾的esp值:x+4+4+4+(0xf8-x)
保存的返回地址的位置我们假设为x
现在答案应该是260对吗?为什么我们还要考虑第一次推动(push %ebp
)?