为什么我们需要在向内存地址

时间:2017-11-22 23:23:44

标签: assembly x86 nasm

Explains除非我们在存储地址存储的值中添加立即值时指定大小运算符(例如 byte dword ), NASM将返回错误消息。

section .data           ; Section containing initialized data

    memory_address: db "PIPPACHIP"

section .text           ; Section containing code

global  _start          ; Linker needs this to find the entry point!

_start:

23            mov ebx, memory_address
24            add [ebx], 32

............................................... .........

24:  error: operation size not specified. 

公平公平。

我很好奇为什么会这样。由于以下两段代码将产生相同的结果。

add byte [ebx], 32

add dword [ebx], 32

那它有什么区别? (除了在这个例子中你为什么要使用dword没有多大意义)。这只是因为“NASM这么说”吗?或者这里有一些我缺少的逻辑?

如果汇编程序可以从寄存器名称解密操作数大小,例如add [ebx], eax可以工作,为什么不对立即值执行相同的操作,即只需继续并预先计算立即值的大小。

在向内存地址的值添加立即值时,需要指定大小运算符的要求是什么?

NASM版本2.11.08 架构x86

1 个答案:

答案 0 :(得分:4)

  

由于以下两段代码将产生相同的结果:

add byte [ebx], 32
add dword [ebx], 32

它们只会产生相同的结果,因为'P' + 32不会进入下一个字节。

根据结果设置标志。如果第4个字节的高位设置,那么将为dword版本设置SF

re:关于CF如何运作的评论:

来自添加的结果始终为01。即,两个N位整数之和总是适合(N+1)位整数,其中额外位为CF。可以将add eax, ebx视为在CF:EAX中产生结果,其中每个位可以是0或1,具体取决于输入操作数。

此外,如果ebx指向页面中的最后一个字节,则dword [ebx]可能会出现段错误(如果下一页未映射),但byte [ebx]则不会。

这也有性能影响:字节的读 - 修改 - 写不能存储转发到双字加载,而dword读 - 修改 - 写访问所有4个字节。

由于这些以及其他各种原因,NASM汇编到输出文件中的指令的操作码是add r/m32, imm8还是add r/m8, imm8的操作码是否重要。

这是一件好事,它迫使你明确指出你的意思而不是某种默认。基于直接大小的基础也会令人困惑,尤其是在使用ASCII_casebit equ 0x20常量时。更改常量时,不希望指令的操作数大小发生变化。