1

我使用 gdbinfo registers <tab>查看所有寄存器,但没有看到 MMX 寄存器。

gdb ir 选项卡,没有 mmx 寄存器 mm0-mm7

我的 CPU 是 Xeon Platinum 8163,一个支持 SSE 和 MMX 的现代 Xeon cpu。所以我认为这是一个 gdb 问题(如果我是对的)。

为什么 gdb 不支持显示 mmx 寄存器,而 mmx 寄存器与基本寄存器和 sse 寄存器相比应该具有相同的重要性级别。

4

1 回答 1

1

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
于 2021-06-24T04:27:14.707 回答