我是这里的新手,刚刚开始学习汇编语言.所以,如果我错了,请纠正我,或者如果这篇文章没有任何意义我会删除.
我在讨论x86-64英特尔架构中的数据移动指令.我已经读过,常规movq指令只能有直接的源操作数,可以表示为32位二进制补码数,而movabsq指令可以有任意64位立即数作为其源操作数,并且只能有一个寄存器作为目标.
你能详细说明一下吗?这是否意味着我只能使用movabsq指令移动64位立即值?只有立即价值到登记册?我不知道如何将64位立即值移动到内存中.或者也许我错了一些重要的事情.
理想情况下会有一个用AT&T语法编写的英特尔软件开发人员手册版本,但我很乐意找到足够接近的版本.
在x64上,可以通过以下方式从64位绝对地址加载(即,取消引用64位立即数)
movabs addr64, %rax
但是,当目标寄存器不是rax汇编程序给出错误消息时operand size mismatch for movabs.我错过了什么?
所以我正在我的mac上学习x86_64 nasm程序集以获得乐趣.在hello world和一些基本的算术之后,我尝试从这个站点复制一个稍高级的hello world程序并将其修改为64位intel,但我无法摆脱这一个错误消息:hello.s:53: error: Mach-O 64-bit format does not support 32-bit absolute addresses.这是我用来汇编和链接的命令:nasm -f macho64 hello.s && ld -macosx_version_min 10.6 hello.o.这是相关的:
cmp rsi, name+8
rsi是我在循环中用于索引的寄存器,name是为用户输入保留的四字,这是名称,到目前为止已经写入了.
这是代码的一部分(要查看其余部分,单击链接并转到底部,唯一的区别是我使用64位寄存器):
loopAgain:
mov al, [rsi]           ; al is a 1 byte register
cmp al, 0x0a            ; if al holds an ascii newline...
je exitLoop             ; then jump to label exitLoop
; If al does not hold an ascii newline...
mov rax, 0x2000004      ; System call write = 4 …我正在阅读Intel x86_64 指南 vol.1以刷新内存寻址的工作方式。
仍然,
3.7.5 指定偏移
内存地址的偏移部分可以直接指定为静态值(称为位移)或通过由以下一个或多个组件组成的地址计算指定:
• 位移— 8 位、16 位或32 位值。
我在Agner Fog 的汇编指南中读到,当与 (r/e)ax 寄存器一起使用时,64 位绝对寻址是可能的。
所以..
是否可以使用具有 64 位地址的绝对寻址来 jmp、mov 和 call(使用所有寄存器),或者我是否必须继续使用 Base + 位移组合?
让我们MOV EAX,[0xFFFFFFFF]以64位模式将指令编码为67A1FFFFFFFF(有效地址大小由67前缀从默认的64位切换为32位)。
英特尔指令参考手册(从2015年12月起,文档订购号:325383-057US)在第Vol。2A 2-11说:
2.2.1.3
64位模式下的位移寻址使用现有的32位ModR / M和SIB编码。ModR / M和SIB大小不变。它们保留为8位或32位,并被符号扩展为64位。
这表明应该对32bit位移进行符号扩展,但是我不确定这是否也涉及特殊的moffs寻址模式。英特尔在下一页上说:
2.2.1.6 RIP相对寻址
RIP相对寻址是通过64位模式而不是64位地址大小启用的。地址大小前缀的使用不会禁用RIP相对寻址。地址大小前缀的作用是将计算的有效地址截断并将其零扩展为32位。
这表明在相对寻址模式下,将disp32符号扩展到64位,再添加到RIP,然后截断并进行零扩展。但是,我不确定同一规则是否适用于绝对寻址模式,MOV moffs操作就是这种情况。
从A)FFFFFFFFFFFFFFFF或B)00000000FFFFFFFF将EAX加载到哪个地址?
我有一个内存位置,其中包含一个我想要与另一个角色进行比较的角色(并且它不在堆栈的顶部,所以我不能只是pop它).如何引用内存位置的内容以便进行比较?
基本上我如何在语法上做到这一点.
考虑一个简单的指令,例如
mov RCX, RDI          # 48 89 f9
48 是 x86_64 的 REX 前缀。它不是LCP。但请考虑添加 LCP(用于对齐目的):
.byte 0x67
mov RCX, RDI          # 67 48 89 f9
67 是地址大小前缀,在本例中用于没有地址的指令。该指令也没有立即数,并且不使用 F7 操作码(假 LCP 停止;F7 将是 TEST、NOT、NEG、MUL、IMUL、DIV + IDIV)。假设它也不跨越 16 字节边界。这些是 Intel优化参考手册中提到的 LCP 停顿情况。
该指令是否会导致 LCP 停顿(在 Skylake、Haswell 等上)?两个 LCP 怎么样?
我日常驾驶的是 MacBook。所以我无法访问 VTune,也无法查看 ILD_STALL 事件。还有其他方法可以知道吗?
performance assembly x86-64 cpu-architecture micro-optimization
我们假设.data部分有以下项目:
0x1234 00010203 04050607 08090a0b 0c0d0e0f
0x1238 10000000
在代码中,
mov $0x1234, %eax
mov 0x1238, %ebx
我相信使用$符号,它将是常数,因此%eax将具有内存地址,但%ebx呢?
两条指令究竟有什么不同?