返回介绍

2. 常量

发布于 2024-10-13 10:58:56 字数 3488 浏览 0 评论 0 收藏 0

最简单的方法是用 equ 定义一个整型常量。

可在 .text、.data、.bss 内使用。

len: equ 10

常见的使用方式,是用 $ 进行地址减法获取数据长度。

$ 表示 nasm 编译后当前指令位置。

$$ 表示当前 section 起始位置。

section .data    
  s: db 'hello', 10, 0  ; \n\NULL
  n: equ $ - s      ; 7
section .data    
  s: db 'hello', 10, 0  ; \n\NULL
  n: equ $ - s      ; 7

  x: dq 0         ; qword 8
  m: equ $ - $$     ; 7 + 8 = 15  常量语句不会分配空间。

常量值有:

  • 整型常量
  • 字符常量
  • 字符串常量
  • 浮点常量
200      ; 十进制(默认)
0200     ; 十进制(和其他语言 0 前缀表示八进制有所区别)
0200d    ; 十进制,d 后缀。
0d200    ; 十进制,0d 前缀。

0c8h     ; 十六进制,h 后缀。(避免 c8h 被当作符号,添加 0 前缀)
$0c8     ; 十六进制,$0 前缀。
0xc8     ; 十六进制,0x 前缀。
0hc8     ; 十六进制,0h 前缀。

310q     ; 八进制,q 后缀。
310o     ; 八进制,o 后缀。
0q310    ; 八进制,0q 前缀。
0o310    ; 八进制,0o 前缀。

11001000b  ; 二进制,b 后缀。
0b1100_1000  ; 二进制,0b 前缀,带下划线分隔符。

字符常量以单引号( ' )、双引号( " )或反引号( ` )表达。字符常量代表 ASCII 值,多个字符以小端顺序排列,支持八和十六进制转义。

mov rax, 'a'          ; 0x61
mov rax, 'abcd'         ; 0x64636261
mov rax, `\x61\x62\x63\x64`   ; 0x64636261

字符串常量表示按顺序提供多个值。

section .rodata
  s1: db 'abcd', 10, 0      ; \n\NULL
  s2: db 'a','b','c','d', 10, 0

字符串从左到右依次写入,这和字符表示单个整数的小端排列不同。

global _start

section .rodata
  x: db 'ab', 10, 0  ; string 
  y: equ 'ab'    ; const 0x6261

section .text
  _start:
    mov   rax, y

  exit:
    mov   rax, 60
    xor   rdi, rdi
    syscall
0000000000401000 <_start>:
  401000:  b8 61 62 00 00       mov  eax,0x6261
    
Hex dump of section '.rodata':
  0x00402000 61620a00              ab..

%assign、%define

以下方式,会在预处理时进行文本替换,可重新定义。

  • %assign : 常量值(表达式),不支持参数。
  • %define : 单行宏,支持参数。

注意符号区分大小写。

global _start

%assign X 100
%define index(size, n)  size [x + n]

section .data
  x times 10 db 0
  n equ $ - x

section .text
  _start:
    ; --- equ ---------------------------------
    mov   rax, n  ; 展开

    ; --- $, $$ -------------------------------
    mov   rax, $$   ; .text 开始地址
    mov   rbx, $  ; 当前地址

    ; --- %assgin ----------------------------
    mov   rcx, X  ; 展开

    %assign X 200   ; 重定义
    mov   rdx, X  ; 展开

    ; --- %define ----------------------------
    mov index(byte, 2), 0x88  ; mov byte [x + 2], 0x88
    mov rax, index(qword, 2)  ; mov rax, qword [x + 2]
$ nasm -E test.s

[global _start]

[section .data]
  x times 10 db 0
  n equ $ - x

[section .text]
  _start:
    mov rax, n        ; equ 需要编译处理。

    mov rax, $$       ; $、$$ 需要编译处理。
    mov rbx, $

    mov rcx, 100      ; %assign 被替换。
    mov rdx, 200

    mov byte [x + 2], 0x88  ; %define 被替换。
    mov rax, qword [x + 2]
$ nm ./test
0000000000402000 d x


$ objdump -d -M intel ./test

0000000000401000 <_start>:
  401000:  b8 0a 00 00 00       mov  eax,0xa
  401005:  48 b8 00 10 40 00 00   movabs rax,0x401000        ; .text 起始地址
  40100c:  00 00 00 
  40100f:  48 bb 0f 10 40 00 00   movabs rbx,0x40100f        ; 当前地址
  401016:  00 00 00 
  401019:  b9 64 00 00 00       mov  ecx,0x64
  40101e:  ba c8 00 00 00       mov  edx,0xc8
  401023:  c6 04 25 02 20 40 00   mov  BYTE PTR ds:0x402002,0x88 ; 地址常量被计算
  40102a:  88 
  40102b:  48 8b 04 25 02 20 40   mov  rax,QWORD PTR ds:0x402002
  401032:  00 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文