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

x86_64寄存器RAX/EAX/AX/AL覆盖完整寄存器内容[重复]

杜经艺
2023-03-14
0x1122334455667788
  ================ rax (64 bits)
          ======== eax (32 bits)
              ====  ax (16 bits)
              ==    ah (8 bits)
                ==  al (8 bits)
mov  eax, 0x11112222 ; eax = 0x11112222
mov  ax, 0x3333      ; eax = 0x11113333 (works, only low 16 bits changed)
mov  al, 0x44        ; eax = 0x11113344 (works, only low 8 bits changed)
mov  ah, 0x55        ; eax = 0x11115544 (works, only high 8 bits changed)
xor  ah, ah          ; eax = 0x11110044 (works, only high 8 bits cleared)
mov  eax, 0x11112222 ; eax = 0x11112222
xor  al, al          ; eax = 0x11112200 (works, only low 8 bits cleared)
mov  eax, 0x11112222 ; eax = 0x11112222
xor  ax, ax          ; eax = 0x11110000 (works, only low 16 bits cleared)
mov  rax, 0x1111222233334444 ;           rax = 0x1111222233334444
mov  eax, 0x55556666         ; actual:   rax = 0x0000000055556666
                             ; expected: rax = 0x1111222255556666
                             ; upper 32 bits seem to be lost!
mov  rax, 0x1111222233334444 ;           rax = 0x1111222233334444
mov  ax, 0x7777              ;           rax = 0x1111222233337777 (works!)
mov  rax, 0x1111222233334444 ;           rax = 0x1111222233334444
xor  eax, eax                ; actual:   rax = 0x0000000000000000
                             ; expected: rax = 0x1111222200000000
                             ; again, it wiped whole register

所以,我有两个问题:

>

  • 我认为这种尴尬的行为必须在某个地方记录下来,但我似乎找不到详细的解释(关于64位寄存器的32位高值是如何被清除的)。对EAX的写入总是擦除RAX,还是更复杂?它是否适用于所有64位寄存器,或者有一些例外?

    一个非常相关的问题提到了同样的行为,但是,唉,再次没有确切的文档参考。

    只是我,还是这整件事看起来真的很奇怪和不合逻辑(即eax-ax-ah-al,rax-ax-ah-al有一种行为,rax-eax有另一种行为)?也许我在这里遗漏了一些重要的一点,为什么它会这样实现?

    对“为什么”的解释将非常感谢。

  • 共有1个答案

    明安阳
    2023-03-14

    在Intel/AMD处理器手册中记录的处理器模型对于现代核心的真正执行引擎来说是一个相当不完美的模型。特别是,处理器寄存器的概念与现实不符,不存在EAX或RAX寄存器。

    指令解码器的一个主要工作是将遗留的x86/x64指令转换成微操作,即类RISC处理器的指令。易于并发执行并能够利用多个执行子单元的小指令。允许多达6条指令同时执行。

    为了做到这一点,处理器寄存器的概念也被虚拟化了。指令解码器从一个大的寄存器组中分配一个寄存器。当指令退出时,动态分配的寄存器的值被写回当前保存值的寄存器,比如RAX。

     类似资料:
    • 我正在尝试编写一个引导加载程序,我正在编写的所有代码都在实模式下运行。在我发现的所有示例中,要么是要么是,我不明白这是在做什么。它似乎与设置段寄存器有关,但我不清楚是什么。

    • Vim提供了许多寄存器。可以将这些寄存器用作多个剪贴板。使用多个文件时,此功能非常有用。在本章中,将讨论以下主题内容 - 复制寄存器中的文本 粘贴寄存器中的文本 列出可用的寄存器 寄存器类型 1. 复制寄存器中的文本 对于复制,可以使用普通的命令,即并将其存储在寄存器中,可以使用以下语法 - 例如,要复制寄存器中的文本,请使用以下命令 - 2. 粘贴寄存器中的文本 从寄存器粘贴文本 - 例如,下面

    • 当前的Perl 5虚拟机是一台堆栈机器。 它通过将操作保持在堆栈上来传递操作之间的值。 操作将值加载到堆栈上,执行他们需要执行的操作并将结果放回堆栈。 这很容易使用,但速度很慢。 要将两个数字相加,您需要执行三次堆栈推送和两次堆栈弹出。 更糟糕的是,堆栈必须在运行时增长,这意味着在您不想分配内存时分配内存。 因此,Parrot将打破虚拟机的既定传统,并使用寄存器架构,更类似于真实硬件CPU的架构。

    • 处理器操作主要涉及处理数据。 该数据可以存储在存储器中并从其上访问。 然而,从存储器读取数据和将数据存储到存储器中会降低处理器的速度,因为它涉及通过控制总线向存储器存储单元发送数据请求并通过相同通道获取数据的复杂过程。 为了加速处理器操作,处理器包括一些内部存储器存储位置,称为registers 。 寄存器存储数据元素以便处理而无需访问存储器。 处理器芯片内置有限数量的寄存器。 处理器寄存器 IA

    • 80386中应用程序员感兴趣的有16个寄存器。如图2-5所示,这些寄存器被分成以下几个基本类型: 1.通用寄存器。这些32为通用寄存器主要用来数学和逻辑运算。 2.段寄存器。这些特殊目的寄存器允许系统软件设计者选择平坦模式或是段模式。这六个寄存器决定了,任何时候,哪段存储器可以被寻址。 3.状态和指令寄存器。这些特殊目的寄存器用于记录和改变80386处理器状态的一些特征。 2.3.1 通用寄存器

    • Intel 80386寄存器 这里假定读者对80386 CPU有一定的了解,所以只作简单介绍。80386的寄存器可以分为8组:通用寄存器,段寄存器,指令指针寄存器,标志寄存器,系统地址寄存器,控制寄存器,调试寄存器,测试寄存器,它们的宽度都是32位。一般程序员看到的寄存器包括通用寄存器,段寄存器,指令指针寄存器,标志寄存器。 General Register(通用寄存器):EAX/EBX/ECX/