数据定义与伪指令

伪指令(Pseudo-instruction)是写给编译器看的指令,不是 CPU 执行的机器指令。它们告诉编译器如何分配内存、定义数据、处理符号等。

伪指令 vs 机器指令

  • 机器指令:编译后变成机器码,CPU 执行,如 movaddjmp
  • 伪指令:编译时由编译器处理,不产生机器码,如 dbdwassumeoffsetend

数据定义伪指令

db — 定义字节(Define Byte)

每个数据占 1 字节(8位),可以定义数字、字符、字符串:

data segment
    db 1                ; 定义1个字节,值为 01H
    db 'a'              ; 定义1个字节,值为 61H('a'的ASCII码)
    db 'hello'          ; 定义5个字节,每个字符占1字节
    db 01H, 02H, 03H   ; 定义3个字节
data ends

dw — 定义字(Define Word)

每个数据占 1 个字 = 2 字节(16位)

data segment
    dw 1234H            ; 定义1个字,值为 1234H
    dw 'ab'             ; 定义1个字,'a'在低字节,'b'在高字节
    dw 0, 1, 2          ; 定义3个字
data ends

dw 的字符串限制

dw 每个数据项必须是 2 字节,所以 dw 'abc' 会报错(3个字节无法凑成整数个字)。 字符串请用 db 定义,dw 只能用于长度为偶数的短字符串(如 'ab')。

dd — 定义双字(Define Double Word)

每个数据占 2 个字 = 4 字节(32位)

data segment
    dd 12345678H        ; 定义1个双字,占4字节
data ends

内存布局遵循小端序(Little Endian)dd 12345678H 在内存中存储为 78 56 34 12(低字节在低地址)。

dup — 重复操作符

dupdb/dw/dd 配合使用,用于批量定义重复数据:

db 3 dup(0)             ; 定义3个字节的0,相当于 db 0,0,0
db 3 dup(0,1,2)         ; 定义9个字节:0,1,2,0,1,2,0,1,2
db 3 dup('abcABC')      ; 定义18个字节:'abcABC'重复3次

dw 5 dup(0)             ; 定义5个字的0
dd 10 dup(?)            ; 定义10个双字,? 表示不初始化(值不确定)

格式:

db 重复次数 dup(重复内容)
dw 重复次数 dup(重复内容)
dd 重复次数 dup(重复内容)

offset — 取偏移地址

offset 是编译器处理的操作符,功能是取得标号的偏移地址

code segment
start:
    mov ax, offset start    ; ax = start 标号的偏移地址(编译时计算)
    mov si, offset data     ; si = data 标号的偏移地址
code ends

offset vs lea

  • offset编译时计算,是个常量
  • lea ax, [bx+si+8]运行时计算,可以处理动态地址 两者都能取地址,但使用场景不同。

数据在内存中的布局(小端序)

8086 采用小端序存储多字节数据:低字节存低地址,高字节存高地址

data segment
    db 1          ; data:0 → 01H(1字节)
    dw 1          ; data:1 → 01H, data:2 → 00H(2字节,小端序)
    dd 1          ; data:3 → 01H, data:4 → 00H, data:5 → 00H, data:6 → 00H(4字节)
data ends

程序结构伪指令

segment / ends — 定义段

段名 segment
    ; 段的内容
段名 ends

一个程序可以有多个段(代码段、数据段、栈段),详见 05-多段程序设计

end — 程序结束标记

end 告诉编译器”源程序到此结束”,后面可以跟程序入口标号:

end start       ; 告诉编译器程序入口是 start 标号

assume — 段寄存器关联

assume 将段寄存器和程序中定义的段关联起来,它是伪指令,不会自动设置段寄存器的值,只是告诉编译器在编译时如何处理段名引用。

assume cs:code, ds:data, ss:stack

详见 05-多段程序设计

数据定义示例

data segment
    ; 数字
    bval  db  255           ; 字节
    wval  dw  65535         ; 字
    dval  dd  12345678H     ; 双字

    ; 字符串
    msg   db  'Hello, World!', 0DH, 0AH, '$'  ; 字符串 + 回车换行 + $结束符

    ; 数组
    arr   dw  10 dup(0)     ; 10个字的数组,初始化为0

    ; 未初始化空间
    buf   db  128 dup(?)    ; 128字节的缓冲区
data ends

相关