我使用 gdbinfo registers <tab>
查看所有寄存器,但没有看到 MMX 寄存器。
我的 CPU 是 Xeon Platinum 8163,一个支持 SSE 和 MMX 的现代 Xeon cpu。所以我认为这是一个 gdb 问题(如果我是对的)。
为什么 gdb 不支持显示 mmx 寄存器,而 mmx 寄存器与基本寄存器和 sse 寄存器相比应该具有相同的重要性级别。
我使用 gdbinfo registers <tab>
查看所有寄存器,但没有看到 MMX 寄存器。
我的 CPU 是 Xeon Platinum 8163,一个支持 SSE 和 MMX 的现代 Xeon cpu。所以我认为这是一个 gdb 问题(如果我是对的)。
为什么 gdb 不支持显示 mmx 寄存器,而 mmx 寄存器与基本寄存器和 sse 寄存器相比应该具有相同的重要性级别。
MMX 寄存器没有自己独立的架构状态;他们为 x87 寄存器 st0..st7 起别名。(英特尔这样做是为了让操作系统不会特别支持通过 FXSAVE/FXRSTOR 在上下文切换时保存/恢复 MMX 状态)。这与所有其他寄存器不同。
但我认为这是一个 GDB 错误,而不是故意决定不公开 MMX 状态,除非通过 x87 状态。 info reg mmx
制表符完成但什么也不打印。(x86-64 Arch GNU/Linux 上的 GDB 10.1)
即使在 MMX 状态下运行 FPU 的程序(movd mm0, eax
例如在执行之后),它仍然没有完成制表符。事实上,即使p $mm0
只是打印 void(因为 GDB 变量名不被识别为绑定到 MMX 寄存器)。
您可以通过以下方式查看 MMX 状态i r float
例如在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 指令(如fld
. (在像 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