在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汇编的怪癖).
此循环在英特尔Conroe/Merom上每3个周期运行一次,imul按预期方式在吞吐量方面存在瓶颈.但是在Haswell/Skylake上,它每11个循环运行一次,显然是因为setnz al它依赖于最后一个循环imul.
; synthetic micro-benchmark to test partial-register renaming
mov ecx, 1000000000
.loop: ; do{
imul eax, eax ; a dep chain with high latency but also high throughput
imul eax, eax
imul eax, eax
dec ecx ; set ZF, independent of old ZF. (Use sub ecx,1 on Silvermont/KNL or P4)
setnz al ; ****** Does this depend on RAX as well as ZF?
movzx eax, al
jnz .loop ; }while(ecx);
Run Code Online (Sandbox Code Playgroud)
如果setnz al …
我注意到GHC的代码生成器当前没有输出使用任何较低机器寄存器的程序集al.甚至字节大小的操作也是rax在64位和eax32位机器上实现的.然而,GCC经常使用这些较小的寄存器.
是否有使用小的寄存器的任何真正的性能优势样al?
到目前为止我听到的一个建议是操作码inc al小于inc rax(但不小于inc eax).是否存在使用小寄存器的其他非性能因素?
我在 Windows 10 上,安装了 Cygwin。我一直在使用 Cygwin 编译/汇编 c 和汇编程序,使用 Cygwin 安装的“gcc”和“nasm”。据我所知,nasm 有一个 -f win64 模式,所以它可以组装 64 位程序。现在,对于 windows 上的 x64 汇编编程,youtube 似乎缺少教程。youtube 上的大多数汇编编程教程都是针对 x64 linux 或 x32 windows 的,我需要能够在 x64 windows 上将字符串打印到控制台,而无需使用任何外部函数,例如 C 的“printf”。
对我不起作用的 StackOverflow 链接:
据我所知,nasm 确实支持使用 -f win64 扩展名的 64 位窗口。此外,答案与如何在 x64 位窗口上以汇编形式编写实际程序无关
如何在Windows下用汇编程序编写hello world?
所有给出代码的答案都只给出了过时的 Windows 版本(32 位)的代码,除了一个。我尝试了适用于 64 位的一个答案,但是链接目标文件的命令给了我一个错误,即系统找不到指定的路径。
该站点不包含任何代码,这正是我所需要的。另外,我正在尝试用 nasm 编写 Hello World 程序。
该问题实际上包含一个 hello world 程序的代码,但是在 Windows 10(我的设备)上的 cygwin 下执行时,我遇到了分段错误。