如何理解“CMPL $为0x0,-0x30(%RBP)” /“济......”
-0x30(%ebp)
并不意味着要使用的值%ebp - 0x30
。这是一个内存地址来读取。该指令(cmpl
)的后缀为l
,所以它处理的是4字节的数量。所以实际发生的是它从地址%ebp - 0x30
中读取一个4字节的数字并检查它是否为零。
(该$
前缀意味着它是一个直接的价值,而不是一个地址。这就是为什么0x0
是从字面上,而不是取消引用。)
非常感谢!但是现在我怎么才能知道%ebp的价值是什么,因为它直接读取4字节内存。我对此一无所知。 – James
@James好吧,假设代码在调用'read_six_numbers'之前将'%ebp-0x30'的地址加载到'%rsi'(第一个参数)中,我认为这是'read_six_numbers'放置结果的地方;即它是6个整数的缓冲区的开始。这与48 = 6 \ * 8的大小(对于6个8字节整数)是一致的......除非这样做没有意义,因为我们只比较4个字节的整数。嗯... – melpomene
它是'%rbp',而不是'%ebp'。这是一个64位指针(对4个字节的内存)。它在这个函数中被用作帧指针,所以它的高32位不全是零,'0x30(%ebp)'会出现段错误。 –
你不需要知道的rbp
值拆除炸弹的引信,它的总是用相对的方式来处理某些内存部分。它设置在启动由序列:
pushq %rbp
movq %rsp, %rbp
pushq %r12
pushq %rbx
subq $0x20, %rsp
这确实推动老rbp
值到栈(保存它),然后将rbp
到当前堆栈指针值(rsp
)。所以(%rbp)
现在包含旧的rbp
。然后通过将另外两个寄存器r12
和rbx
推入堆栈(现在生成rsp == rbp - 16
)来保存它们。然后rsp
再次被减去32,即rsp == rbp - 48
。
这是常见的模式,如何为局部变量分配内存空间,即任何进一步的push
指令都将使用低于rbp - 48
的内存。内存从rbp - 48
到rbp - 17
(增量)未定义,可以*用作“局部变量”内存。然后在rbp - 16
存储8字节原始rbx
值,在rbp - 8
存储原始r12
值,并在rbp
存储旧rbp
。 (我的意思是所有的“rbp-x”被用作内存地址来存储内存中的值)
然后你的代码调用输入6个数字,我猜的意思是32位整数(由下面的代码判断),所以它提供了地址为rbp - 48
。 6 * 4 = 24 =>输入值将存储在地址rbp - 48
直到(含)rbp - 25
的存储器中。
注“未使用的内存”从rbp - 24
高达rbp - 17
的差距,这是另一个8个字节的备用本地存储,不使用你发布的代码,这是由编译器中加入极有可能的留白,使rsp
callq read_six_numbers
之前正确对齐。
所以基本上你不需要知道哪儿rsp/rbp
点,它指向一些有效的堆栈存储器(可能是,或代码将崩溃,而炸弹将不爆炸......有点怪设计:))))。您可以在开始时选取任意值,如0x8000
(rsp
),然后用此模拟运行。 (即<+11> leaq -0x30,(%rbp), %rsi
然后rsi = 0x7FC8;
(为0x8000 - 8 - 的0x30)
什么-x(%rbp)
意味着各种指令(要注意的“内存操作数”使用的lea
VS <any other instruction>
语义差别休息时,lea
确实只有内存地址计算,而其他指令只是以此为起点,使用计算得到的地址访问存储在内存中的实际值)在其他答案+注释中进行了描述,并使用x86指令参考指南并通过一些教程再次阅读,直到它
通过进入“read_six_numbers”我知道输入是6个数字,并且有一些模式 – James
Do不张贴文字的图片。从终端复制/粘贴。 –
[请勿放置文字图像](https://meta.*.com/q/303812/995714) –