首页 > 解决方案 > 这个汇编代码用 ascii 做什么?

问题描述

我试图理解以下汇编代码(x86-64 att):

msg: .ascii "This is an examp" # please note it's examp not example

_start:

  mov $msg, %rsi
  mov $1, %rdi
  mov $1, %rdx
  mov $1, %rax
  mov $0, %rbx
  mov $16, %r9
  call exm


exm:
  cmp %rbx, %r9
  je end
  test $1, %rbx
  jnz skip
  syscall

skip:
  inc %rsi
  inc %rbx
  call exm

end:
  ret
  1. 将字符串存储在寄存器中是什么意思?寄存器不是保持 0/1 吗?

  2. 如果它正在转换 ascci ti chars,我知道 char 大小是 1 个字节,我们的字符串是 16 个字母,所以我们需要 16 个字节,而寄存器只有 8 个字节。那个怎么样?

  3. 因为 rdi 是 1 我们正在从屏幕读取,这是真的吗?

  4. 如果系统调用失败,它将返回 0,如果存储在 rax 中,则返回值,这是否意味着存在无限循环的可能性?

标签: assemblyasciix86-64system-callscpu-registers

解决方案


将字符串存储在寄存器中是什么意思?寄存器不是保持 0/1 吗?

不知道你说的0/1是什么意思,但是msg是一个标签,基本上等于字符串的起始地址。所以mov $msg, %rsi将字符串的起始地址移动"This is an examp"%rsi.

如果它正在转换 ascci ti chars,我知道 char 大小是 1 个字节,我们的字符串是 16 个字母,所以我们需要 16 个字节,而寄存器只有 8 个字节。那个怎么样?

同样,寄存器只保存字符串的起始地址。

因为 rdi 是 1 我们正在从屏幕读取,这是真的吗?

不从屏幕读取,写入屏幕。您正在使用write系统调用,在其中输入要写入的文件描述符 in %rdi1isstdout的文件描述符,因此它写入终端屏幕。

如果系统调用失败,它将返回 0,如果存储在 rax 中,则返回值,这是否意味着存在无限循环的可能性?

write错误时返回-errno(所以是一个负数),而不是 0。查看手册页中可能出现的错误,我看不出您的程序有任何可能的错误原因。由于您的程序依赖于返回值 1 fromwrite来继续调用write,如果确实发生错误,您将调用一个不存在的系统调用(因为没有负数系统调用),在这种情况下不会发生任何事情并将rax设置为-ENOSYS(似乎-38来自我所做的测试),这又不是有效的系统调用号。我尝试编辑您的程序以故意以无效的系统调用号开头,而不是1它不会导致无限循环,它只是不打印任何内容并退出。因此,您的程序似乎不会导致无限循环。

我不确定在某些情况下,对 write 的正确调用是否可以从您的程序返回 0 (意味着它不打印任何内容),但如果确实如此,那么下一个调用将是 toread并且您的程序冻结,直到您输入一些字符串(read的参数与 非常相似write,因此尽管是一个完全不同的系统调用,但它似乎仍会正常运行,尽管由于它似乎msg是在 中定义的.text,因此您无法写入它并且-EFAULT也会为此返回)。同样,这只是假设在某些情况下write返回 0;我发现这极不可能,甚至可能是不可能的。


推荐阅读