如果将定义为字节的字值大小的字节移动到32位寄存器,就像定义为dword,会发生什么情况?

时间:2019-03-14 20:49:48

标签: assembly x86

代码如下:

;NASM

section .data
a dw 0xDEAD

section .text 
...
mov eax, dword [a + 1]
; eax now equals 0xDE
...

那么,这如何工作?汇编知道,如果我移动的字节数超过了定义的字节数,那么它只是在高位加零?还是这段代码仅对我有用,并且通常是未定义的行为或类似的东西?

2 个答案:

答案 0 :(得分:2)

a dw 0xDEAD

告诉汇编器存储2个字节(DW-定义Word(16bit),btw-DB = 8bit,DD = 32bit)并使用a指向它。由于(我敢打赌)您使用的是x86-64机器,因此它是“ little endian”,这意味着它将首先存储从最低有效字节开始的多字节值,因此,您的0xDEAD值将按以下方式存储:{{ 1}},然后0xAD。由于您的数据段肯定要填充为例如16个字节的倍数,因此可能用零填充。现在,如果我们假设您的数据段为16个字节-前2个定义您的0xDE变量-其余的将为零。

现在数据段看起来像这样(假设零填充到16个字节)(不带0x前缀的十六进制值):

a

通过编写AD, DE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ^ \__ (a+1) points here at DE ,您告诉汇编程序以一种将从地址dword ptr [a + 1]抓取dword(4个字节)的方式对此类机器代码指令进行编码。 这些将是字节:     DE,0,0,0 由于(如我之前所述)x86的字节序为低字节,如果将其读取为4字节值,则表示a+1,因此EAX等于该值。

当然,您的数据段可能不是16个字节,但可能是完整的页面长度,但这毫无意义。

答案 1 :(得分:1)

即使您的计算机变成了一片废墟,也已被“定义”用于组装。 df.groupby([df.dow, df.hour, df.minute]).rolling(5).apply(pd.quantile, [0.25, 0.30, 0.50])中的“类型转换” dword仅通知汇编器您知道自己在做什么,并且不想收到警告或错误。在目标文件中,类型已经消失,处理器不知道您移动的字节数超过了定义的字节数。

处理器从地址a + 1读取4个字节,并且随机或非随机地存在值mov eax, dword [a + 1]。这些零点如何到达那里并不重要。可能是NASM的文本段已对齐,也可能是操作系统已为数据段请求了整个页面(4096字节),并用零填充了其余部分,也可能是文本段以零开始,因为进入点更远。该程序的行为也有可能在某个时候随机改变。

TLDR:不要这样做!