在表达式中减去 NASM 宏的意外结果
Unexpected result of subtracting a NASM macro in an expression
我写了下面的代码:
section .text
%define len msg-4
global _start
msg: db "Thank you"
var: dd 0x31323334
_start:
mov ecx, msg
debug:
mov edx, var-len ; **** the problem is here
mov ebx, 1
mov eax, 4
int 80h
mov eax, 1
mov ebx, 1
int 80h ; exit
我希望 edx 保持值 13,因为 var-len= var-msg+4= 13
(var 地址与 msg 的距离是 9,因为 msg 是 9 个字节)。因此,我认为这段代码会打印 "Thank you"。
但是,edx 得到了 5,并且打印了 "Thank"。
为什么edx得到5而不是13?
看看最上面的一行 - 你说
section .text
%define len msg-4
global _start
msg: db "Thank you"
var: dd 0x31323334
msg - 4,而不是 msg + 4。这就解释了您所看到的差异。
%define len msg-4
是文本替换,见下文。
一般的方法是在一个对象后面加上$ - start
来计算长度。简单地标记结束也是有效的。
section .rodata ; groups read-only together inside the .text section
msg: db "Thank you"
var: db 0x34, 0x33, 0x32, 0x31 ; dd 0x31323334 ; Since you're passing these bytes to write(2), writing them separately is probably less confusing. (x86 is little-endian, so they will come out "backwards")
;; apparently you want to include var as part of the message, for some reason
msglen equ $ - msg ; $ is the current position
;; msgend: ; alternative: label the end. There doesn't have to be a db or anything; it's fine to have multiple labels for the same address
section .text
global _start
_start:
mov edx, msglen ; message length
;; mov edx, msgend - msg ; alternative
为什么你得到了5
%define
是一个文本替换,就像 C 预处理器。如果您使用 (msg-4)
,它会按您预期的方式工作。在 CPP 宏中虔诚地使用 ()
的所有原因也适用于此。
%define len msg-4 ; first of all, this is a terrible name: it's not the length!
mov edx, var - len ; expands to var-msg-4, not var - (msg-4)
%define msg_minus_varlen (msg-4)
mov edx, var - msg_minus_varlen; expands to var - (msg-4)
这仍然是一种非常令人困惑的方法。您可以通过从实际要打印的缓冲区中减去偏移量相同的两个位置来获得长度。
我写了下面的代码:
section .text
%define len msg-4
global _start
msg: db "Thank you"
var: dd 0x31323334
_start:
mov ecx, msg
debug:
mov edx, var-len ; **** the problem is here
mov ebx, 1
mov eax, 4
int 80h
mov eax, 1
mov ebx, 1
int 80h ; exit
我希望 edx 保持值 13,因为 var-len= var-msg+4= 13
(var 地址与 msg 的距离是 9,因为 msg 是 9 个字节)。因此,我认为这段代码会打印 "Thank you"。
但是,edx 得到了 5,并且打印了 "Thank"。
为什么edx得到5而不是13?
看看最上面的一行 - 你说
section .text
%define len msg-4
global _start
msg: db "Thank you"
var: dd 0x31323334
msg - 4,而不是 msg + 4。这就解释了您所看到的差异。
%define len msg-4
是文本替换,见下文。
一般的方法是在一个对象后面加上$ - start
来计算长度。简单地标记结束也是有效的。
section .rodata ; groups read-only together inside the .text section
msg: db "Thank you"
var: db 0x34, 0x33, 0x32, 0x31 ; dd 0x31323334 ; Since you're passing these bytes to write(2), writing them separately is probably less confusing. (x86 is little-endian, so they will come out "backwards")
;; apparently you want to include var as part of the message, for some reason
msglen equ $ - msg ; $ is the current position
;; msgend: ; alternative: label the end. There doesn't have to be a db or anything; it's fine to have multiple labels for the same address
section .text
global _start
_start:
mov edx, msglen ; message length
;; mov edx, msgend - msg ; alternative
为什么你得到了5
%define
是一个文本替换,就像 C 预处理器。如果您使用 (msg-4)
,它会按您预期的方式工作。在 CPP 宏中虔诚地使用 ()
的所有原因也适用于此。
%define len msg-4 ; first of all, this is a terrible name: it's not the length!
mov edx, var - len ; expands to var-msg-4, not var - (msg-4)
%define msg_minus_varlen (msg-4)
mov edx, var - msg_minus_varlen; expands to var - (msg-4)
这仍然是一种非常令人困惑的方法。您可以通过从实际要打印的缓冲区中减去偏移量相同的两个位置来获得长度。