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

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

问题描述

解释除非我们在将立即值添加到存储在内存地址的值时指定大小运算符(例如 byte dword ),否则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.

add byte [ebx], 32

add dword [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

推荐答案

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

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个字节的高位已设置,则将对dword版本设置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.

这也有性能影响:一个字节的读取-修改-写入不能存储到dword负载,并且dword读取-修改-写入将访问所有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.

由于这些以及其他各种原因,对于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天全站免登陆