我有这个汇编代码:
foo:
pushl %ebp
mov %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
sub $0x12c, %esp
movl $0x1, (%esp)
movl $0x2, 0x4(%esp)
movl $0x3, 0x8(%esp)
movl $0x4, 0xc(%esp)
我试图找到代码末尾%esp的值与保存的返回地址的位置(%ebp?)之间的差异。基本上,我试图了解%esp正在发生的事情。我知道move将一个值/覆盖一个值放入一个寄存器,我认为在寄存器前面放一个数字来定义寄存器中的那个位置。那么,
movl $0x1, (%esp)
movl $0x2, 0x4(%esp)
movl $0x3, 0x8(%esp)
movl $0x4, 0xc(%esp)
将1插入%esp的第一个插槽,2插入%esp的第4个插槽,3插入%esp的第8个插槽,将4插入%esp的c(第12个)插槽中这会导致100200030004吗?
另外,我真的不明白
sub $0x12c, %esp
,
我以为你必须在数字之前把寄存器减去,否则我错了?我不知道如何从%esp。
据我了解,非" sub"和" mov"线条并不真正相关。
我对组装非常新,但我花了很多时间来解决这个问题,但我仍然觉得很难理解它的作用。有人可以帮助我吗?
答案 0 :(得分:4)
首先回答你的标题问题:寄存器是CPU芯片上的N位存储,通过"移动值"在寄存器中,您将其所有位设置为特定状态(0/1)。如果您"移动多个号码"在寄存器中,每个分配都会覆盖整个寄存器,即最后分配的值在寄存器中,先前的分配值会丢失。
...
movl $0x1, (%esp)
movl $0x2, 0x4(%esp)
movl $0x3, 0x8(%esp)
movl $0x4, 0xc(%esp)
这不会将任何内容移动到注册表中。
这是英特尔语法(如果您不确定,检查AT& T语法,它是如何工作的,它非常棘手,例如仅仅存在$
数值前显着改变指令的含义,$
是它的立即值,没有它是要访问的存储器地址......但是通过寄存器访问存储器需要括号,偏移在外面,索引寄存器的乘数在里面...通常很难为我阅读,英特尔语法更多"人类" IMO):
mov [esp],dword 1
mov [esp+4],dword 2
mov [esp+8],dword 3
mov [esp+12],dword 4
这意味着32位值(1,2,3,4)存储在16字节的存储器中,从地址&#34开始;当前值存储在寄存器esp
"。
因此,如果esp
在此代码之前是0x8F001000
,那么内存就是:
address byte values (content)
0x8F001000 CC CC CC CC DE AD DE AD CC CC CC CC DE AD DE AD
0x8F001010 AA BB CC CC 00 11 DE AD AA BB CC CC 00 11 DE AD
然后在运行该段代码后,内存内容将更改为:
address byte values (content)
0x8F001000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
0x8F001010 AA BB CC CC 00 11 DE AD AA BB CC CC 00 11 DE AD
esp
中的值将保持不变,仍为0x8F001000
。