MMX 寄存器没有自己独立的架构状态;他们为 x87 寄存器 st0..st7 起别名。 (英特尔这样做是为了让操作系统不会特别支持通过 FXSAVE/FXRSTOR 在上下文切换时保存/恢复 MMX 状态)。这与所有其他寄存器不同。
但我认为这是一个 GDB 错误,而不是故意决定不公开 MMX 状态,除非通过 x87 状态。 info reg mmx tab-completes 但什么也不打印。 (x86-64 Arch GNU/Linux 上的 GDB 10.1)
即使在 FPU 处于 MMX 状态时运行程序(例如,在执行movd mm0, eax 之后),它仍然没有完成制表符。事实上,即使p $mm0 也只是打印 void(因为 GDB 变量名未被识别为与 MMX 寄存器相关联)。
您可以通过i r float
查看 MMX 状态
例如在mov eax, 231/movd mm0, eax之后,
starti
stepi
si
(gdb) p $mm0
$1 = void
(gdb) i r mm0
Invalid register `mm0'
(gdb) i r mmx
(gdb) i r float
st0 <invalid float value> (raw 0xffff00000000000000e7)
st1 0 (raw 0x00000000000000000000)
...
又一个步骤,pshufw mm1, mm0, 0
(gdb) si
0x000000000040100c in ?? ()
(gdb) i r float
st0 <invalid float value> (raw 0xffff00000000000000e7)
st1 <invalid float value> (raw 0xffff00e700e700e700e7)
st2 0 (raw 0x00000000000000000000)
所以如果忽略 80 位扩展精度位模式的高 16 位,可以将 64 位尾数部分视为 MMX 寄存器值。
我认为这个问题已经很久没有解决了,因为 SSE2 使 MMX 大部分 过时了,提供了更多更宽的寄存器,并且不需要慢速 emms 在像 @ 这样的潜在 x87 FPU 指令之前离开 MMX 状态987654331@。 (在像 Skylake 这样的现代 CPU 上,MMX 指令没有 mov-elimination,并且有些指令在比 SSE2 等价物更少的执行端口上运行,例如 paddd)
当然,一些现有的代码,特别是 x264 和 FFmpeg 的 h.264 软件解码器,仍然使用手写的 MMX asm 而不是 XMM 寄存器的低位 qword。这有时是有利的,例如允许punpcklbw mm0, [rdi]。
顺便说一句,我单步执行的测试程序是从这个 NASM 源组装 + 链接到静态可执行文件中的:
mov eax, 231 ; __NR_exit_group = 0xe7
movd mm0, eax
pshufw mm1, mm0, 0 ; broadcast the low word
emms
nop
syscall