gcc 上的 bswap 结果可能不正确

bswap result on gcc possibly incorrect

我正在处理汇编(我的小端 Linux 框上的 ATT 语法)并且发现 bswap 指令存在问题。我的代码如下:

 .code32
.section .data
stringa:
  .asciz "eax is now %x\n"
stringb:
  .asciz "ebx is now %x\n"
.section .text  
.globl main
main:
  movl , %eax
  movl ,  %ebx
  xchg %eax, %ebx
  pushl %eax
  pushl $stringa
  call printf
  add , %esp
  pushl %ebx
  pushl $stringb
  call printf
  add , %esp
  bswap %eax
  pushl %eax
  pushl $stringa
  call printf
  add , %esp
  call exit

注意输出:

remnux@remnux:~/Assembly$ .​​/swap

eax 现在是 5

ebx 现在是 4

eax 现在是 d000000

请注意,当我在调试时转储寄存器时,gbd 显示 0x5000000(预期结果)。

5 在标准输出的混洗字节中变为 d(十六进制 13)(但不在寄存器转储中。)这告诉我第一个字节的第 4 位显示为(不正确?)翻转。如果我以十进制执行此操作,则会出现相同的结果,尽管它显然更难破译:5 变为 218103808 而不是预期的 83886080。只需将 2^27 添加到 83886080,您就会看到发生了什么。

这是预期的吗,为什么?请注意,我在我的 64 位 Ubuntu VM 上使用 32 位代码:

remnux@remnux:~/Assembly$ uname -m

x86_64

EAX 中的值不会跨函数调用保留。实际上printf会returnEAX中的一个值,写入的字符数。在本例中为 13,即 ebx is now 4 中的字符数加上一个换行符。因此,您正在字节交换 printf 的 return 值,而不是您之前加载到 EAX 中的值。