我写了以下代码:
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个字节)。因此,我认为这段代码会打印“谢谢”。
但相反,edx得到了5,并且打印了“谢谢”。
为什么edx得到5而不是13 ?
答案 0 :(得分:6)
%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)
这仍然是一个非常令人困惑的方式。你通过从你实际要打印的缓冲区中减去相同数量的两个位置来获得长度。
答案 1 :(得分:0)
看看最上面的一行 - 你说
section .text
%define len msg-4
global _start
msg: db "Thank you"
var: dd 0x31323334
msg - 4,而不是msg + 4.那就在那里解释了你所看到的差异。