相关疑难解决方法(0)

为什么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万
查看次数

为什么GCC会生成mov%eax,%eax以及它是什么意思?

GCC 4.4.3生成了以下x86_64程序集.令我困惑的部分是mov %eax,%eax.将寄存器移到自身?为什么?

   23b6c:       31 c9                   xor    %ecx,%ecx        ; the 0 value for shift
   23b6e:       80 7f 60 00             cmpb   $0x0,0x60(%rdi)  ; is it shifted?
   23b72:       74 03                   je     23b77
   23b74:       8b 4f 64                mov    0x64(%rdi),%ecx  ; is shifted so load shift value to ecx
   23b77:       48 8b 57 38             mov    0x38(%rdi),%rdx  ; map base
   23b7b:       48 03 57 58             add    0x58(%rdi),%rdx  ; plus offset to value
   23b7f:       8b 02                   mov    (%rdx),%eax      ; load map_used value to eax …
Run Code Online (Sandbox Code Playgroud)

assembly gcc x86-64

27
推荐指数
1
解决办法
9194
查看次数

R代表RAX,RBX,RCX,RDX,RSI,RDI,RBP,RSP?

x86汇编语言不得不改变,因为x86处理器架构已经从8位变为16位变为32位,现在变为64位.

我知道在32位汇编程序寄存器名称(EAX,EBX等)中,每个名称的E前缀代表扩展意味着32位形式的寄存器而不是16位形式(AX,BX等).

这些寄存器名称的R前缀在64位中代表什么?

x86 assembly x86-64 cpu-architecture cpu-registers

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

C++ int vs 64位机器中的long long

我的计算机有64位处理器,并且当我寻找sizeof(int),sizeof(long)以及sizeof(long long),事实证明,INT为32位,和长长为64位.我研究了原因,看来普遍的假设是说C++ 中的int符合机器的字大小是错误的.据我所知,编译器需要定义大小,我的是Mingw-w64.我研究的原因是理解如果小于字大小的类型的使用有利于速度(例如,int)或它是否具有负面影响.在32位系统中,一种流行的观点是:由于字大小为int,short将被转换为int,这将导致额外的位移等,从而导致更差的性能.反对意见是缓存级别会有好处(我没有深入研究),使用short会对虚拟内存经济有用.所以,除了这种困境之间的混淆之外,我还面临着另一个问题.我的系统是64位,如果我使用intshort并不重要,它仍然会小于字大小,我开始认为使用64位长的长度不是很有效,因为它是在系统设计的级别.另外我读到还有另一个约束,即OS的库(ILP64,LP64),它定义了类型大小.在ILP64中,与LP64相比,默认int为64位,如果我使用支持ILP64的操作系统,它会加速程序吗?一旦我开始询问我应该使用哪种类型来加速我的C++程序,我就面临更深层次的主题,其中我没有专业知识,而且一些解释似乎相互矛盾.你能解释一下:

1)如果最佳做法是在x64中使用long long来实现最高性能,即使对于1-4字节数据也是如此?

2)使用小于字大小的类型(内存胜利与附加操作)的权衡

3)word和int size是64位的x64计算机是否有可能通过使用所谓的向后兼容性使用16位字大小来处理短路?或者它必须将16位文件放入64位文件中,并且可以完成的事实将系统定​​义为向后兼容.

4)我们可以强制编译器使int 64位?

5)如何将ILP64整合到使用LP64的PC中?

6)使用适用于其他编译器,操作系统和体系结构(32位处理器)的上述问题的代码可能存在哪些问题?

c++ memory performance cpu-word 32bit-64bit

17
推荐指数
1
解决办法
7460
查看次数

在%x86-64上,mov%esi,%esi是否为no-op?

我对Linux内核的一个头文件(arch/x86/include/asm/nops.h)中的注释感到有些困惑.它说明了这一点

<...>以下指令在64位模式下不是nops,对于64位模式,使用K8或P6 nops而不是
movl%esi,%esi
leal 0x00(%esi),%esi
<...>

我想作者暗示机器指令(分别是'89 F6'和'8D 76 00')而不是汇编指令.根据LEA英特尔软件开发人员手册第2A卷中的描述,后一条指令(lea 0x00(%rsi), %esi)与前者相同,mov %esi,%esi.

所以这简化了问题,是否mov %esi,%esi实际上是x86-64上的无操作.

mov不会改变旗帜.这种mov也不会改变记忆.似乎,如果它改变了一些东西%rip,那应该是通用寄存器.但我不知道它如何改变内容%rsi或其他内容.如果你操纵通用寄存器的下半部分,上半部分不应该改变,对吧?

assembly x86-64 linux-kernel

8
推荐指数
2
解决办法
1845
查看次数

xorl%eax,g86生成的x86_64汇编代码中的%eax

我在集会上总是一个菜鸟,只是捅了一下看看发生了什么.无论如何,我写了一个非常简单的函数:

void multA(double *x,long size)
{
  long i;
  for(i=0; i<size; ++i){
    x[i] = 2.4*x[i];
  }
}
Run Code Online (Sandbox Code Playgroud)

我编译它:

gcc -S -m64 -O2 fun.c
Run Code Online (Sandbox Code Playgroud)

我得到了这个:

    .file   "fun.c"
    .text
    .p2align 4,,15
    .globl  multA
    .type   multA, @function
multA:
.LFB34:
    .cfi_startproc
    testq   %rsi, %rsi
    jle .L1
    movsd   .LC0(%rip), %xmm1
    xorl    %eax, %eax
    .p2align 4,,10
    .p2align 3
.L3:
    movsd   (%rdi,%rax,8), %xmm0
    mulsd   %xmm1, %xmm0
    movsd   %xmm0, (%rdi,%rax,8)
    addq    $1, %rax
    cmpq    %rsi, %rax
    jne .L3
.L1:
    rep
    ret
    .cfi_endproc
.LFE34:
    .size   multA, .-multA
    .section    .rodata.cst8,"aM",@progbits,8
    .align …
Run Code Online (Sandbox Code Playgroud)

assembly gcc x86-64

7
推荐指数
1
解决办法
9307
查看次数

是否可以使用"mov eax,0x1"而不是"mov rax,0x1"?

组装此代码时nasm:

BITS 64
mov eax, 0x1
mov rax, 0x1
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

b8 01 00 00 00 b8 01 00 00 00
Run Code Online (Sandbox Code Playgroud)

这是mov eax, 0x1重复两次的操作码.

这是否意味着mov rax, 0x1可以随时被替换mov eax, 0x1,或只是在这种情况下?

如果这是正确的,那么使用它不是更好:

xor rax, rax
inc rax
Run Code Online (Sandbox Code Playgroud)

因为组装时变为6个字节,而mov eax, 0x1只有5个字节?

assembly x86-64 nasm zero-extension

6
推荐指数
1
解决办法
1879
查看次数

MOVZX缺少32位寄存器到64位寄存器

这是复制(转换)未签名寄存器的指令:http : //www.felixcloutier.com/x86/MOVZX.html

基本上,该指令具有8-> 16、8-> 32、8-> 64、16-> 32和16-> 64。

32-> 64转换在哪里?我需要为此使用签名版本吗?
如果是这样,如何将全64位用于无符号整数?

assembly x86-64 instruction-set

4
推荐指数
1
解决办法
1469
查看次数