标签: cpu-registers

178
推荐指数
6
解决办法
22万
查看次数

为什么32位寄存器上的x86-64指令归零整个64位寄存器的上半部分?

x86-64 Tour of Intel Manuals中,我读到了

也许最令人惊讶的事实是,诸如MOV EAX, EBX自动将指令的高32位归零的指令RAX.

同一来源引用的英特尔文档(3.4.1.1 64位手动基本架构中的通用寄存器)告诉我们:

  • 64位操作数在目标通用寄存器中生成64位结果.
  • 32位操作数生成32位结果,在目标通用寄存器中零扩展为64位结果.
  • 8位和16位操作数生成8位或16位结果.目标通用寄存器的高56位或48位(分别)不会被操作修改.如果8位或16位操作的结果用于64位地址计算,则将寄存器显式符号扩展为完整的64位.

在x86-32和x86-64汇编中,16位指令如

mov ax, bx
Run Code Online (Sandbox Code Playgroud)

不要表现出这种"奇怪"的行为,即eax的上层词被归零.

因此:引入这种行为的原因是什么?乍一看似乎不合逻辑(但原因可能是我习惯了x86-32汇编的怪癖).

x86 assembly x86-64 cpu-registers zero-extension

97
推荐指数
3
解决办法
2万
查看次数

为什么基于JVM堆栈和Dalvik VM注册?

我很好奇,为什么Sun决定以JVM堆栈为基础,Google决定以DalvikVM注册为基础?

我想JVM不能真正假设目标平台上有一定数量的寄存器,因为它应该是平台无关的.因此,它只是将寄存器分配等推迟到JIT编译器.(如我错了请纠正我.)

所以Android人员认为,"嘿,那效率很低,让我们马上去找一个基于寄存器的vm ......"?但等等,有多个不同的Android设备,Dalvik的目标是多少个寄存器?Dalvik操作码是否针对一定数量的寄存器进行了硬编码?

目前市场上所有Android设备的寄存器数量是否相同?或者,是否在dex-loading期间执行了寄存器重新分配?这一切如何结合在一起?

jvm computer-architecture dalvik cpu-registers vm-implementation

95
推荐指数
3
解决办法
2万
查看次数

如果寄存器如此快速,为什么我们不能拥有更多?

在32位,我们有8个"通用"寄存器.使用64位,数量翻倍,但它似乎独立于64位变化本身.
现在,如果寄存器如此之快(没有存储器访问),为什么它们自然不存在呢?CPU构建器不应该在CPU中使用尽可能多的寄存器吗?为什么我们只有我们拥有的金额的逻辑限制是什么?

performance assembly history cpu-registers

85
推荐指数
2
解决办法
6303
查看次数

什么是"FS"/"GS"寄存器?

所以我知道以下寄存器及其用途应该是什么:

  • CS =代码段(用于IP)

  • DS =数据段(用于MOV)

  • ES =目标段(用于MOVS等)

  • SS =堆栈段(用于SP)

但是以下哪些寄存器用于什么?

  • FS ="文件段"?

  • GS = ???

注意:我不是在询问任何特定的操作系统 - 我问的是CPU的用途是什么,如果有的话.

x86 assembly cpu-registers

85
推荐指数
5
解决办法
7万
查看次数

x86_64寄存器rax/eax/ax/al覆盖完整寄存器内容

正如广泛宣传的那样,现代x86_64处理器具有64位寄存器,可以以向后兼容的方式用作32位寄存器,16位寄存器甚至8位寄存器,例如:

0x1122334455667788
  ================ rax (64 bits)
          ======== eax (32 bits)
              ====  ax (16 bits)
              ==    ah (8 bits)
                ==  al (8 bits)
Run Code Online (Sandbox Code Playgroud)

这样的方案可以从字面上理解,即,总是可以使用指定的名称仅访问寄存器的一部分用于读取或写入目的,并且这将是高度逻辑的.实际上,对于高达32位的所有内容都是如此:

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 …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 cpu-registers zero-extension

70
推荐指数
1
解决办法
5万
查看次数

新的X86_64处理器寄存器的名称是什么?

在哪里可以找到用于此体系结构的新寄存器的名称?

我指的是X86中的寄存​​器,如EAX,ESP,EBX等.但我喜欢它们在64位.

我不认为它们与我拆解C代码时的情况相同,我得到r而不是e.

x86 assembly x86-64 cpu-registers

54
推荐指数
4
解决办法
7万
查看次数

程序计数器和指令寄存器

程序计数器保存下一个应该执行的指令的地址,而指令寄存器保存要执行的实际指令.他们中的其中一个不够吗?

这些寄存器中每一个的长度是多少?

谢谢.

cpu-architecture cpu-registers program-counter

42
推荐指数
2
解决办法
7万
查看次数

如何知道变量是在寄存器中还是在堆栈中?

我正在阅读inline关于isocpp FAQ的这个问题,代码是给出的

void f()
{
  int x = /*...*/;
  int y = /*...*/;
  int z = /*...*/;
  // ...code that uses x, y and z...
  g(x, y, z);
  // ...more code that uses x, y and z...
 }
Run Code Online (Sandbox Code Playgroud)

然后它说

假设一个典型的C++实现具有寄存器和堆栈,寄存器和参数在调用之前就被写入堆栈g(),然后从堆栈内部g()读取参数 并再次读取以在g()返回时 恢复寄存器f().但是,这是一个很多不必要的阅读和写作的,尤其是当编译器能够使用寄存器变量的情况下x, yz:每个变量可以被写入两次(如寄存器,也可以作为一个参数)和出两次(在使用时g()和在返回期间恢复寄存器f()).

我很难理解上面的段落.我尝试列出我的问题如下:

  1. 对于计算机对驻留在主存储器中的某些数据执行某些操作,是否必须首先将数据加载到某些寄存器然后CPU才能对数据进行操作?(我知道这个问题与C++没有特别的关系,但理解这个问题将有助于理解C++的工作原理.)
  2. 我认为f()函数的功能与g(x, y, z)函数相同.x, y, z在调用之前如何进入g()寄存器,传入的参数g() …

c++ cpu-registers

42
推荐指数
4
解决办法
5595
查看次数

什么是被调用者和调用者保存的寄存器?

我在理解调用者和被调用者保存的寄存器之间的区别以及何时使用什么方面遇到了一些麻烦.

我使用的是MSP430:

程序:

mov.w #0,R7 
mov.w #0,R6 
add.w R6,R7 
inc.w R6 
cmp.w R12,R6 
jl l$loop 
mov.w R7,R12
ret
Run Code Online (Sandbox Code Playgroud)

上面的代码是被调用者,并且在教科书示例中使用,因此它遵循惯例.R6和R7被呼叫者保存,R12被呼叫者保存.我的理解是被调用者保存的regs不是"全局的",因为在过程中改变它的值不会影响它在程序之外的值.这就是您必须在开头将新值保存到被调用者注册表中的原因.

R12,保存的来电者是"全球性的",因为缺乏更好的词汇.该程序在通话后对R12产生持久影响.

我的理解是否正确?我错过了其他的东西吗?

assembly abi cpu-registers calling-convention

40
推荐指数
3
解决办法
8万
查看次数