Tag: x86

为什么循环指令很慢? 英特尔能不能有效地实现它?

loop递减ecx / rcx,然后在非零时跳转 。 速度很慢,但英特尔不能以低廉的速度让它变得更快? 一个dec和分支uop已经是可能的了(唯一的区别是设置标志)。 从Agner Fog的指令表中 loop使用各种微架构: K8 / K10:7米 推土机家族/ Ryzen:1 m-op(与macros电子testing分支相同的成本,或jecxz ) P4:4个jecxz (与jecxz相同) P6(PII / PIII):8个 Pentium M,Core2:11 uops Nehalem:6个uops。 (11 loope / loopne ) SnB系列:7个。 (11个为loope / loopne )。 对于jecxz只有2个jecxz Silvermont:7个uops AMD捷豹(低功耗):8个微处理器,5c吞吐量 通过Nano3000:2微软 难道解码器只是解码像lea rcx, [rcx-1] / jrcxz ? 那将是3个微笑。 至less在没有地址大小的前缀的情况下是这样,否则如果跳转被使用,则必须使用ecx并截断RIP到EIP 。 也许地址大小控制的减less宽度的奇数select解释了许多微软。 或者更好,只是将它解码为一个融合的十进制分支,不设置标志? jnz上的dec ecx / jnz解码为单个uop(设置标志)。 我知道真正的代码并没有使用它(因为它至lessP5或者其他东西已经很慢了),但是AMD决定让推土机变得很快是值得的。 […]

引用内存位置的内容。 (x86寻址模式)

我有一个内存位置包含一个字符,我想与另一个字符比较(它不在堆栈的顶部,所以我不能只是pop它)。 我如何引用一个内存位置的内容,以便我可以比较它? 基本上,我怎样才能在语法上做到这一点。

在64位系统(GNU工具链)上组装32位二进制文​​件

我编写可以编译的汇编代码: as power.s -o power.o 链接power.o目标文件时出现问题: ld power.o -o power 为了在64位操作系统(Ubuntu 14.04)上运行,我在power.s文件的开头添加了power.s ,但是我仍然得到错误: 分割故障(核心转储) power.s : .code32 .section .data .section .text .global _start _start: pushl $3 pushl $2 call power addl $8, %esp pushl %eax pushl $2 pushl $5 call power addl $8, %esp popl %ebx addl %eax, %ebx movl $1, %eax int $0x80 .type […]

为什么大部分的x64指令会将32位寄存器的上半部分清零?

今天我了解了x64程序集(资料来源: http : //x86asm.net/articles/x86-64-tour-of-intel-manuals/ ) 也许最令人惊讶的事实是,诸如MOV EAX,EBX之类的指令自动将RAX寄存器的高32位清零。 英特尔文档(3.4.1.1通用基本体系结构中的64位模式的通用寄存器)在同一来源中引用告诉我们: 64位操作数在目标通用寄存器中生成一个64位结果。 32位操作数产生一个32位结果,在目标通用寄存器中零扩展为一个64位结果。 8位和16位操作数生成8位或16位结果。 目标通用寄存器的高56位或48位(分别)不会被操作修改。 如果8位或16位操作的结果是用于64位地址计算的,则明确地将寄存器扩展为完整的64位。 在x86-32汇编中,16位指令如 mov ax, bx 不要performance出这种eax的上位字“零”的“奇怪”的行为。 因此:这种行为被引入的原因是什么? 乍一看这似乎不合逻辑(但原因可能是我习惯了x86-32汇编的怪癖)。

微融合和寻址模式

使用英特尔®架构代码分析器 (IACA),我发现了一些意想不到的情况(对我来说)。 以下指令使用[base+index]寻址 addps xmm1, xmmword ptr [rsi+rax*1] 根据IACA没有微熔丝。 但是,如果我这样使用[base+offset] addps xmm1, xmmword ptr [rsi] IACA报告说它确实融合了。 “ 英特尔优化参考手册”第2-11部分提供了以下内容作为“可由所有解码器处理的微型熔合微操作” FADD DOUBLE PTR [RDI + RSI*8] Agner Fog的优化组装手册也给出了使用[base+index]寻址的微操作融合的例子。 例如,请参见第12.2节“Core2上的相同示例”。 那么正确的答案是什么?

在x86汇编中将寄存器设置为零的最佳方法是什么?xor,mov或and?

以下所有说明都执行相同的操作:将%eax设置为零。 哪种方法是最佳的(需要最less的机器周期)? xorl %eax, %eax mov $0, %eax andl $0, %eax

LEA指令的目的是什么?

对我来说,这只是一个时髦的MOV。 它的目的是什么?我什么时候可以使用它?

如何确定.NET程序集是为x86还是x64构建的?

我有一个.NET程序集的任意列表。 我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。 这可能吗?

在C ++内联asm中使用基指针寄存器

我希望能够在内联asm中使用基指针寄存器( %rbp )。 一个玩具的例子就是这样的: void Foo(int &x) { asm volatile ("pushq %%rbp;" // 'prologue' "movq %%rsp, %%rbp;" // 'prologue' "subq $12, %%rsp;" // make room "movl $5, -12(%%rbp);" // some asm instruction "movq %%rbp, %%rsp;" // 'epilogue' "popq %%rbp;" // 'epilogue' : : : ); x = 5; } int main() { int x; Foo(x); […]