在NASM汇编中,有db
和dw
伪指令来声明数据。NASM Manual提供了几个示例,但没有直接说明它们之间的区别。我用下面的"hello world“代码对它们进行了测试,结果发现没有明显的区别。我怀疑distinct与内部数据格式有关,但我不知道如何检查。
section .data
msg db "hello world",10,13,0
msg2 dw "hello world",10,13,0
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg ; or use msg2
mov rdx, 14
syscall
jmp .exit
.exit:
mov rax, 60
mov rdi, 0
syscall
发布于 2015-01-22 05:52:04
NASM无论如何都会生成单词;-)
dw 'a'
等效于dw 0x61
,并将单词0x0061 (大端)存储为61 00
(小端)。
dw 'ab'
(小端)等同于dw 0x6261
(大端)并存储61 62
(小端)。
dw 'abc'
(一个字,一个字节)等同于dw 0x6261, 0x63
,并存储两个字(小端):61 62 63 00
。
dw 'abcd'
(两个单词)存储两个单词:61 62 63 64
。
msg2 dw "hello world",10,13,0
将字符串转换为6个单词,将数字转换为3个单词,并将其存储:68 65 6C 6C 6F 20 77 6F 72 6C 64 00 0A 00 0D 00
。在您的示例中,msg直到它的末尾才会被打印。
发布于 2015-01-22 06:05:22
NASM手册中的3.2.1 DB and Friends: Declaring Initialized Data和3.4.2 Character Strings部分指出,当单个字符串比元素大小短时,就会有所不同。每个元素都用零字节填充到其本机大小。
为确保数据中不包含意外字符,请始终使用DB for 8位字符串。根据机器字节顺序和代码中的任何假设,DW可能适用于UTF-16,也可能不适用。
使用DW伪指令肯定会导致数值的意外值,因为这些值将被解释为在字符串中引入意外空字符的16位字。
使用2.1.3 The -l Option: Generating a Listing File查看正在输出的实际内存映像,以查看您正在生成的内容。
发布于 2019-04-28 02:54:50
NASM还支持多字符字面量,就像在接受整数的任何上下文中的'ab'
一样,例如add ax, '00'
与0x3030
相同。(可能用于unpacked BCD->ASCII转换。)
NASM对多字符文字的字节排序在内存中产生的顺序与little-endian x86上的源顺序相同。例如,mov eax, '1234'
/ mov [buf], eax
将在内存中生成与buf: db '1', '2', '3', '4'
相同的4字节序列。mov
-immediate指令被编码为b8 31 32 33 34
,因为x86立即操作数使用小端,就像数据加载/存储一样。
对于args和db
**/**dw
**/**dd
**/etc**:有一种特殊情况,而不是像( add ax, '123456'
)那样截断(foo.asm:1: warning: word data exceeds bounds [-w+number-overflow]
)为了只保留整数值的低位字节/字/双字,ASCII或UTF-8字符串被视为多个元素。
,但最后一个元素用零字填充(在末尾,因为小端),以使总大小是元素大小( dw的单词/ dword的dd /等)的倍数。
所以所有这些都是完全等同的
db 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x00
db 'a', 'b', 'c', 'd', 'e', 'f', 'g', 0
db 'abcdefg', 0
db `abcdefg\0` ; C-style escapes like \n or \0 work inside backtick strings only. (NASM only, not YASM)
dw 'abcdefg' ; 7 bytes padded to 4 words = 8
dw 'ab', 'cd', 'ef', 'g' ; 'g' is a small WORD value
dw 0x6261, 0x6463, 0x6665, 0x0067 ; x86 is little-endian (LSB first) but we write integer values with MSD on the left
dd 'abcdefg' ; 7 bytes padded to 2 dwords = 8
对于dd
和dq
(以及do
和其他更广泛的类型),您可以有超过1个字节的零,但总是在末尾。例如,dd 'abcde'
是db 'abcde', 0,0,0
。
有关 的信息,请参阅NASM手册
源值和像0x123456
这样的整数值没有"endianness“。这是对术语的误用。
字节序是将多字节整数序列化为内存,然后按地址递增的顺序检查各个字节时所看到的效果。
我们的阿拉伯数字从左到右从MSD到LSD的约定与内存中的字节顺序是分开的。
我们也可以在源代码和/或伪代码或任何其他计数系统中使用罗马数字来表示数字。(例如,一元,其中3= 111)。
不过,记住“小字节序把数字倒过来”是一种不错的心理捷径。但它是在字节边界上,而不是十六进制数字(4位)边界。
,但不要陷入认为寄存器中的值是“大端”的陷阱。它们没有字符顺序,除非存储在内存中。
https://stackoverflow.com/questions/28076943
复制相似问题