Assembly 系统写入输出额外字符

Assembly 系统写入输出额外字符,assembly,x86-64,nasm,Assembly,X86 64,Nasm,因此,我正在编写一个基于菜单的程序,它可以显示一条消息(还有一些我还没有实现的东西)。我有以下部分: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, msg_len syscall 无论出于何种原因,这都会输出存储在msg中的字符串,以及存储在.data部分中的所有其他字符串。我已经用gdb运行了这个程序,并在系统调用之前打印了rsi和rdx的内容——它们包含我想要输出的字符串和该字符串的长度,正如预期的那样。但是在系统调用之后,rax包含2048个。如

因此,我正在编写一个基于菜单的程序,它可以显示一条消息(还有一些我还没有实现的东西)。我有以下部分:

mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msg_len
syscall
无论出于何种原因,这都会输出存储在
msg
中的字符串,以及存储在
.data
部分中的所有其他字符串。我已经用gdb运行了这个程序,并在系统调用之前打印了rsi和rdx的内容——它们包含我想要输出的字符串和该字符串的长度,正如预期的那样。但是在系统调用之后,
rax
包含2048个。如果我理解正确,这意味着写入控制台的字符数比我在系统调用之前指定的30个多2048个。我猜我的其他字符串是在
msg
存储在内存中之后存储的,这就是它们获得输出的原因,但为什么它忽略了rdx


值得一提的是,如果
msg\u len
是不可变的,那么代码就可以正常工作,但我需要它是可变的,因为
msg
可以更改。

您说过,当您尝试只输出其中一个字符串时,它会输出所有字符串,称为
msg


您可以使用
CMP
JE
(或
JZ
,它们相同)进行循环,直到
NULL
。然后,您可以将此数字用作
LEN
来打印字符串

mov rdx,msg_len
不会加载
msg_len
的地址而不是存储在那里的值吗?不会,它加载存储在那里的值。我查过了。当你说“可变”时,你是指标记一些静态存储的
msg\u len:dq msg-$
?如果是这样,那么是的,
mov rdx,msg_len
将地址放入寄存器,并且
sys_write
一直运行,直到它到达未映射内存(因为这比非常大的长度要快)。IIRC,它实际上返回写入的长度,而不是
-EFAULT
。否则,您可能在错误的位置执行了
msg\u len eq msg-$
,比如在所有数据之后。无论如何,这显然不是一个。TL:DR:assemble time eq常量与内存中的数据是使用符号/标签的完全不同的方式,而不是“可变”与“不可变”。我知道你说你打印了RDX,但你确定打印时没有取消引用它吗?系统调用不会。你是在Linux下运行的,对吗?