【问题标题】:sys_write outputting extra characterssys_write 输出额外字符
【发布时间】:2019-10-27 16:20:31
【问题描述】:

所以我正在编写一个基于菜单的程序,它可以显示一条消息(以及我尚未实现的其他功能)。我有以下部分:

mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msg_len
syscall

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

不管怎样,如果msg_len 是不可变的,代码可以正常工作,但我需要它是可变的,因为msg 可以改变。

【问题讨论】:

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

标签: assembly x86-64 nasm


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多