首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >定义字符串时db和dw的区别

定义字符串时db和dw的区别
EN

Stack Overflow用户
提问于 2015-01-22 05:14:36
回答 3查看 2.9K关注 0票数 3

在NASM汇编中,有dbdw伪指令来声明数据。NASM Manual提供了几个示例,但没有直接说明它们之间的区别。我用下面的"hello world“代码对它们进行了测试,结果发现没有明显的区别。我怀疑distinct与内部数据格式有关,但我不知道如何检查。

代码语言:javascript
运行
复制
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
EN

回答 3

Stack Overflow用户

发布于 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直到它的末尾才会被打印。

票数 2
EN

Stack Overflow用户

发布于 2015-01-22 06:05:22

NASM手册中的3.2.1 DB and Friends: Declaring Initialized Data3.4.2 Character Strings部分指出,当单个字符串比元素大小短时,就会有所不同。每个元素都用零字节填充到其本机大小。

为确保数据中不包含意外字符,请始终使用DB for 8位字符串。根据机器字节顺序和代码中的任何假设,DW可能适用于UTF-16,也可能不适用。

使用DW伪指令肯定会导致数值的意外值,因为这些值将被解释为在字符串中引入意外空字符的16位字。

使用2.1.3 The -l Option: Generating a Listing File查看正在输出的实际内存映像,以查看您正在生成的内容。

票数 2
EN

Stack Overflow用户

发布于 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 /等)的倍数。

所以所有这些都是完全等同的

代码语言:javascript
运行
复制
 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

对于dddq (以及do和其他更广泛的类型),您可以有超过1个字节的零,但总是在末尾。例如,dd 'abcde'db 'abcde', 0,0,0

有关 的信息,请参阅NASM手册

源值和像0x123456这样的整数值没有"endianness“。这是对术语的误用。

字节序是将多字节整数序列化为内存,然后按地址递增的顺序检查各个字节时所看到的效果。

我们的阿拉伯数字从左到右从MSD到LSD的约定与内存中的字节顺序是分开的。

我们也可以在源代码和/或伪代码或任何其他计数系统中使用罗马数字来表示数字。(例如,一元,其中3= 111)。

不过,记住“小字节序把数字倒过来”是一种不错的心理捷径。但它是在字节边界上,而不是十六进制数字(4位)边界。

,但不要陷入认为寄存器中的值是“大端”的陷阱。它们没有字符顺序,除非存储在内存中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28076943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档