Explains除非我们在向存储器地址存储的值添加立即值时指定大小运算符(例如字节或双字),否则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 回答
它们只产生相同的结果,因为
'P' + 32
不会进入下一个字节 .根据结果设置标志 . 如果第4个字节的高位设置,那么将为dword版本设置
SF
.re:关于CF如何工作的评论:
从添加中执行始终是
0
或1
. 即,两个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
常量时 . 更改常量时,不希望更改指令的操作数大小 .