记忆在英特尔上的表现32

时间:2016-05-09 08:25:43

标签: memory assembly intel malware

我知道内存寻址可以用字大小的倍数来完成,因此对于Intel 32位,用于在汇编中分配堆栈中的内存可以用

完成
    //pseudo code
    sub , esp ,4 // so for allocating for a integer on stack
    sub esp, 8 // for a buffer of size 5 for example b[5] 

所以寻址是用4的倍数完成的。因此,也可以使用

来引用堆栈上的本地和参数
     // referring to variable --ebp-4

但有时在反汇编中我会看到一些指示,如

     movb   $0x41, 0xffffffff(%ebp)   ,// refer to ebp-1 for example

所以它指的是1个字节的内存。

所以它指的是一个字节,而不是4个字节的倍数.4个字节的倍数仅用于esp?或者它与每个注册相关?

2 个答案:

答案 0 :(得分:2)

  

4个字节的倍数仅适用于esp?或者它与每个寄存器有关吗?

请注意

sub esp, N

不访问任何内存位置,该用法与内存对齐有关,但指令本身是一个简单的 register-immediate 减法,可以使用任何价值。

出于性能原因,如果读取16位,它们应该是2的地址倍数,32位应该是4的地址倍数。
这称为自然边界对齐

32位系统只能push / pop 16或32位值,如果我们只在sub esp, Npush / {{{{}}等指令中使用4的多个值1}}访问在其自然边界上对齐的数据(注意4是2的倍数)。

也可以使用

等指令直接访问堆栈上的数据

pop

这里的原理是相同的, EBP 是4的倍数(注意它的值是旧的 ESP 值,在减法之前)所以32位数据存储在4的地址倍数(自然对齐)。

字节的自然对齐是...... 1.意思是它们应该是1的地址倍数,即无处不在 这就是mov [ebp-04h], eax执行mov [ebp-01h], 'A'的原因。

琐事

<子> 作为拇指规则 IA32e 通用指令可以在每个地址从字节读取/写入qwords。
整个对齐故事主要是出于性能原因,与RISC机器不同,它们无法在结构上访问未对齐的数据。

<子> 最初引入的SSE指令带有快速“对齐”(如mov [ebp-04h], 'A')和慢速“未对齐”(如movaps)版本的同一指令。

<子> 64位系统现在明确要求堆栈的128位对齐,以便更好地执行向量指令(和加宽寄存器)。

<子> CPU在 EFLAGS 寄存器中有一个位 AC ,它允许程序启用或禁用严格的对齐策略(àlaRISC),假设操作系统已启用此功能(在 CR0 中设置 AM )。

<子> 更严格地对齐数据CPU数据总线(无论在现代集成DRAM控制器上的任何定义)都是毫无意义的 这就是为什么新的ABI在128位上对齐,即使CPU可以有512位寄存器。

<子> 可以在Manual 2 (the complete set)上找到每条指令的对齐要求。

答案 1 :(得分:0)

适用于80x86(所有模式);寻址始终以字节粒度完成。

对于所有正常指令(不包括SSE等扩展),CPU不需要对齐,任何对齐仅仅是出于性能原因。