首页 > 解决方案 > 为什么 AL 寄存器周围没有括号?

问题描述

根据我的理解, %eax 表示 eax 包含的值, (%eax) 表示转到 eax 保留的地址

seta20.1:
inb $0x64, %al        # Wait for not busy
testb $0x2, %al
jnz seta20.1
movb $0xd1,%al        # 0xd1 −> port 0x64
outb %al, $0x64

那么,为什么 %al 周围没有括号呢?因为如果我想通过使用寄存器将 val 移动到地址,我应该这样做:

mov %ebx, (%eax)

正确的?

标签: assemblyx86att

解决方案


inb基本上是从 IO 空间加载到%al. 所以类比是mov (%edx), %al

%al是源 ( out) 或目标 ( in) 寄存器,而不是指针,所以当然不会有括号%al

如果在任何地方都有括号,它将在 IO 空间地址周围,例如(%dx). 或0x64()

但是inb/outb不使用普通寻址模式,它们使用立即%dx数或 IO 空间地址。因此 AT&T 语法在 outb 目标或 inb 源中为它们使用立即或寄存器语法。IO 空间是特殊的,不能像内存一样被寻址。


奇怪的是, AT&T 反汇编objdump -d确实使用(%dx)了非立即形式的端口号,但 GAS 接受%dx(%dx)输入,这对于内联 asm 很方便

当然,两者都组装成相同的机器代码;使用 DX 的指令只有一种形式,字节操作数大小为:https ://www.felixcloutier.com/x86/in 。

   0:   ec                      in     (%dx),%al

llvm-objdump -d用途inb %dx, %al

(%dx)绝不是有效的内存寻址模式:它是一个 16 位寄存器,而不是 BX、BP、SI 或 DI。


推荐阅读