我们来看看这段代码:
mov eax, [esp] ; value of what inside esp
add esp, 4 ; memory or effective address
正如你所能,默认情况下 - 没有[] - 我们在Assembly中使用内存。但是,如果我想将123存储在寄存器中,为什么我不必使用[]?
mov eax, 123 ; is 123 a memory address? or pure value?
因此,123如何处理这里:作为价值或地址?这是一个价值,但为什么不解决?根据前面的示例,它必须是一个地址。或者它取决于注册表?
答案 0 :(得分:1)
mov eax,[esp]
不会将esp
的内容移动到eax中
相反,它将存储在esp中的数字解释为地址,并使用该地址获取内存的内容;然后它返回存储在该内存地址的任何内容。
图形:
esp [0x760001]
memory
1 2 3 4 5 6 7 8 ......
760000 AA BB CC DD FF FF FF FF .....
770000 11 22 33 44 .......
780000 ................
在内存地址0x760001
到0x760004
,我们存储了值DDCCBBAA
(4个字节)。
在内存地址0x760005
到0x760008
,我们存储了值FFFFFFFF
(4个字节)。
每当我们使用[...]
时,我们都在谈论指针。指针是表示存储器中的位置(也称为地址)的数字
如果我们执行mov eax,[esp]
,我们不关心esp的数值,而是关于内存esp指向的内容。
如果我们执行mov eax,esp
,我们会将esp
中的文字值加载到eax
。
如果我们执行mov eax,123
,我们只需使用字面数字123填充eax
。
CPU并不关心寄存器中的数字是文字数字还是地址。它会愉快地执行计算,毕竟地址只是另一个数字。
然而,当我们使用[q]
时,我们告诉CPU要查找位置[q]
的内存包含。
如果我们不使用[]
,我们只是按原样使用寄存器中存储的数字
我们稍后可能再次使用此数字作为指针。
一个例外
唯一例外是lea
指令(例如lea eax,[eax+4]
:eax = eax + 4)。该指令不会在内存中查找任何内容,而是使用数字(可能是也可能不是地址)执行计算。
是否取决于注册?
不,所有寄存器都可以用作双用途寄存器(用于计算和指针)
唯一的例外是esp
指向堆栈。 cpu允许您使用它进行计算,但是如果在发生中断时它不包含有效地址,程序将崩溃。
但是,如果我想将123存储在寄存器中,为什么我不必使用[]?
不,因为值123
将被编码到指令本身中。 cpu不必去内存来检索123
值。获取指令时,它已加载到cpu中。
根据前面的例子,它必须是一个地址。
它可以是地址,因为地址只是一个数字 但是,硬编码地址不太可能。在现代程序中,所有地址都是相对的,因为程序可以在内存中移动。