当前位置: 首页 > 知识库问答 >
问题:

如何知道使用哪个整数寄存器[重复]

严亮
2023-03-14

我正在努力学习组装,这在一定程度上是有意义的,但我有一个问题。我有以下源文件hello.sfml:

; nasm -felf64 hello.asml && ld hello.o

    global _start

    section .text
_start:
    ; write(1, message, 13)
    mov     rax, 1          ; syscall 1 is write
    mov     rdi, 1          ; file handle 1 is stdout
    mov     rsi, message    ; address of string to output
    mov     rdx, 13         ; number of bytes in the string
    syscall                 ; invoke OS to write the string

    ; exit(0)
    mov     rax, 60         ; syscall 60 is exit
    xor     rdi, rdi
    syscall                 ; invoke OS to exit
message:
    db  "Hello, World", 10  ; the 10 is a newline character at the end

很好用。我只是不明白为什么在不同的情况下需要使用特定的整数寄存器。

例如,通过反复试验,我发现当说我想要哪个系统调用时,例如。

    mov     rax, 1  
    ...
    syscall 

我将值1放入整数寄存器RAX,但也可以使用整数寄存器EAXAXALAH

编辑:我的问题不是这个问题的重复,因为这个问题问的是在哪里使用更小的整数寄存器,我问的是一种决定使用哪个整数寄存器的方法。

共有1个答案

孟德曜
2023-03-14

Assembly或x86机器没有定义您应该使用哪个通用寄存器(GPR),您可以使用任何可用的GPR(或提供一个可用的),然而,不同的环境对寄存器的使用和参数传递定义了不同的约定,当您想使用其他人的代码时,您必须遵守这些约定。

具体来说,Linux x86-64使用以下约定,如X86 psABI(第3.2.3节)所述:

如果是标准的用户级代码,这就是在上面的第一个示例中选择RDIRSIRDX的原因,第一个参数在RDI中传递,第二个参数在RSI中传递,第三个参数在RDX中传递。

但是,上面的示例演示了syscalls的Linux内核内部调用约定,它类似于用户级应用程序,但有一些不同(第A.2.1节):

  1. 用户级应用程序用作整数寄存器,用于传递序列%RDI、%RSI、%RDX、%RCX、%R8和%R9。内核接口使用%RDI、%RSI、%RDX、%R10、%R8和%R9。
  2. 系统调用是通过syscall指令完成的。内核销毁寄存器%RCX和%R11.
  3. 必须在寄存器%RAX中传递系统调用的编号。

正如您在示例中所看到的,每个系统调用都根据x86-64的Linux系统调用表定义了rax值(如zx485所注释的那样)。
注意,系统调用最多可以有6个参数,并且与用户级代码不同,代码不能将堆栈用于其他参数。

关于您对ALAX>用法的评论:使用x86-64体系结构时,要求指定rax中的系统调用数,使用寄存器的任何其他部分都是基于运气--如果寄存器其他部分中的所有位都为零,那么您可以使用较低的位--但您不应该信任它。
提醒:

rax is the full 64-bit register
eax is the lower 32-bits
ax is the lower 16-bits
al is the lower 8 bits
ah is the value in bits 8 through 15 

正如您所看到的,使用ah是错误的,并且可能调用不同的系统调用!

 类似资料:
  • 问题内容: 我在Linux Ubuntu服务器中搜索php.ini文件所在的路径,并且在执行命令时发现很多php.ini 。那么如何从php.ini所在的php脚本网页中确切地知道呢? 问题答案: 您可以使用php_ini_loaded_file() 取自php.net: 您可能还需要检查php_ini_scanned_files() 另外,您应该注意,如果从CLI运行PHP脚本,则有可能使用与服

  • 换句话说,你是可以平等地将它们视为存储空间,还是应该坚持将它们用于特定目的?

  • 如何在按钮标题中使用小字母?我正在res/values/strings中创建字符串。带有注册表的xml,但仍有上限。

  • 所以,我有两个问题: > 我认为这种尴尬的行为必须在某个地方记录下来,但我似乎找不到详细的解释(关于64位寄存器的32位高值是如何被清除的)。对的写入总是擦除,还是更复杂?它是否适用于所有64位寄存器,或者有一些例外? 一个非常相关的问题提到了同样的行为,但是,唉,再次没有确切的文档参考。 只是我,还是这整件事看起来真的很奇怪和不合逻辑(即eax-ax-ah-al,rax-ax-ah-al有一种行

  • 本文向大家介绍如何知道MongoDB中使用了哪种存储引擎?,包括了如何知道MongoDB中使用了哪种存储引擎?的使用技巧和注意事项,需要的朋友参考一下 要知道MongoDB中使用了哪种存储引擎,可以使用storageEngine。语法如下- 要了解存储引擎的所有配置详细信息,可以使用以下语法: 让我们实现以上语法,以了解MongoDB中正在使用哪个存储引擎。查询如下- 以下是输出- 为了了解有关上

  • 我需要只使用%RAX、%RBX、%RCX、%RDX、%RSI和%RDI(还有%RSP和%RBP)编写像素化汇编代码 GCC编写的程序集代码: 已将%dl更改为%rdx: