为什么在向内存地址处的值添加立即数时需要消除歧义 [英] Why do we need to disambiguate when adding an immediate value to a value at a memory address

查看:14
本文介绍了为什么在向内存地址处的值添加立即数时需要消除歧义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说明 除非我们指定一个大小操作符(例如bytedword),当向存储在内存地址的值添加立即数时,NASM 将返回错误消息.

Explains that unless we specify a size operator (such as byte or dword) when adding an immediate value to a value stored at a memory address, NASM will return an error message.

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. 

公平的公平.

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

I’m curious as to why this is so however. As the two following segments of code will yield the same result.

添加字节 [ebx], 32

添加双字[ebx], 32

那么它有什么区别呢?(除了对于在这种情况下为什么要使用 dword 没有多大意义).仅仅是因为NASM 这么说"吗?还是这里有一些我缺少的逻辑?

So what difference does it make? (Other than not making much sense as to why you would use dword in this instance). Is it simply because "NASM says so"? Or is there some logic here that I am missing?

如果汇编程序可以从寄存器名称中破译操作数的大小,例如 add [ebx], eax 可以工作,为什么不对立即值做同样的事情,即继续计算预先立即值的大小.

If the assembler can decipher the operand size from a register name, for example add [ebx], eax would work, why not do the same for an immediate value, i.e. just go ahead and calculate the size of the immediate value upfront.

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

What is the requirement that means a size operator needs to be specified when adding an immediate value to a value at a memory address?

NASM 版本 2.11.08架构 x86

NASM version 2.11.08 Architecture x86

推荐答案

确实 出于多种原因,您使用的操作数大小很重要,而且这会很奇怪且不直观/不明显整数值隐含的大小.有歧义时出现 NASM 错误是一个更好的设计,因为两个操作数都不是寄存器.

It does matter what operand-size you use for several reasons, and it would be weird and unintuitive / non-obvious to have the size implied by the integer value. It's a much better design to have NASM error when there's ambiguity because neither operand is a register.

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

As the two following segments of code will yield the same result:

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

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

They only yield the same result because 'P' + 32 doesn't carry into the next byte.

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

Flags are set according to the result. If the 4th byte had its high bit set, then SF would be set for the dword version.

re:关于 CF 工作原理的评论:

re: comments about how CF works:

从添加中执行总是01.即两个 N 位整数的总和总是适合一个 (N+1) 位整数,其中额外的位是 CF.将 add eax, ebx 想象成在 CF:EAX 中产生结果,其中每一位可以是 0 或 1,具体取决于输入操作数.

Carry-out from an add is always 0 or 1. i.e. the sum of two N-bit integers will always fit in an (N+1)-bit integer, where the extra bit is CF. Think of the add eax, ebx as producing the result in CF:EAX, where each bit can be 0 or 1 depending on the input operands.

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

Also, if ebx was pointing at the last byte in a page, then dword [ebx] could segfault (if the next page was unmapped), but byte [ebx] wouldn't.

这也有性能影响:字节的读-修改-写不能存储-转发到双字加载,而双字读-修改-写访问所有 4 个字节.(如果另一个线程在该线程将旧值存储在其上之前刚刚修改了其他字节中的一个,则正确性.)

This also has performance implications: read-modify-write of a byte can't store-forward to a dword load, and a dword read-modify-write accesses all 4 bytes. (And correctness if another thread had just modified one of those other bytes before this thread stored the old value over it.)

由于这些和其他各种原因,NASM 组装到输出文件中的指令的操作码是 add r/m32, imm8 还是 add r/m8 的操作码很重要, imm8.

For these and various other reasons, it matters whether the opcode for the instruction that NASM assembles into the output file is the opcode for add r/m32, imm8 or add r/m8, imm8.

这是一件好事,它迫使您明确表示您的意思,而不是使用某种默认值.基于立即数的大小也会令人困惑,尤其是在使用 ASCII_casebit equ 0x20 常量时.当您更改常量时,您不希望指令的操作数大小发生变化.

It's a Good Thing that it forces you to be explicit about which one you mean instead of having some kind of default. Basing it on the size of the immediate would be confusing, too, especially when using a ASCII_casebit equ 0x20 constant. You don't want the operand-size of your instructions to change when you change a constant.

这篇关于为什么在向内存地址处的值添加立即数时需要消除歧义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆