dq:定义四字
本课属于 Coddy Assembly 学习旅程的“基础知识”单元。第 27 课,共 45 课。
dd 会创建 4 字节的数据。但有时你需要更大的数字或内存地址。这时可以使用 dq:定义四字(Define Quad Word)。
x86 汇编中的四字为 8 字节(64 位)。
语法:
label dq value示例:
section .data
myNumber dq 10000000000 ; 8 字节,值为 10 亿
bigNum dq 123456789012 ; 非常大的数字
address dq msg ; 标签 "msg" 的内存地址对照表:
| 指令 | 大小 | 范围 | 要使用的寄存器 |
|---|---|---|---|
db | 1 字节 | 0 到 255 | al |
dw | 2 字节 | 0 到 65,535 | ax |
dd | 4 字节 | 0 到 4,294,967,295 | eax |
dq | 8 字节 | 非常大(2⁶⁴-1) | rax |
如何在代码中使用四字:
section .data
myNumber dq 5000000000
section .text
mov rax, [myNumber] ; 将值加载到 rax
add rax, 1000000000 ; rax 变为 60 亿
mov [myNumber], rax ; 存回原处特殊用途:存储地址
dq 也用于存储内存地址(指针):
section .data
message db 'Hello', 0
pointer dq message ; 存储 message 的地址重要规则:
| 规则 | 说明 |
|---|---|
使用 rax 进行加载或存储 | rax 是 64 位寄存器 |
挑战
简单在 .data 单元中创建一个名为 universe_age、值为 13800000000 的四字(quad word)。
亲手试试
%include "data.asm"
section .data
msg db 'universe_age = '
msg_len equ $ - msg
newline db 0xa
section .bss
buffer resb 64
section .text
global _start
_start:
; 将四字值加载到 rax
mov rax, [universe_age]
; 将 rax 转换为十进制字符串
mov rsi, buffer
add rsi, 63 ; 移到 buffer 末尾
mov byte [rsi], 0 ; 空字符终止符
mov rcx, 10 ; 十进制转换用的除数
convert_loop:
xor rdx, rdx ; 将 rdx 清零以便除法运算
div rcx ; 用 10 除 rax,rax = 商,rdx = 余数
add dl, '0' ; 将余数转换为 ASCII 字符
dec rsi
mov [rsi], dl ; 存储数字
cmp rax, 0
jnz convert_loop
; 在数字指针和长度被覆盖前,先保存它们
mov r8, rsi ; r8 = 指向第一个数字的指针
mov r9, buffer
add r9, 63
sub r9, rsi ; r9 = 数字的位数
; 输出消息
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msg_len
syscall
; 输出数字
mov rax, 1
mov rdi, 1
mov rsi, r8
mov rdx, r9
syscall
; 输出换行符
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; 退出程序
mov rax, 60
mov rdi, 0
syscall
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: Assembly 在线编辑器