为什么 GCC 会生成导致崩溃的 "mov 0x8,%edx" 指令?

Why does GCC generate a "mov 0x8,%edx" instruction that causes a crash?

我有一个声明如下的函数:

void
tesysLog(W16 uid, char *file, int line, int level,
         W16 state, W16 event, int error, char *format, ...)

上面还有一个func会调用tesysLog,例如:

tesysLog(253, __FILE__, __LINE__, 3, 0, 0, result,
        "error(code = %d) is %d instead of %d\n",
        avp->header.code, decoded, size);   

上述调用的相关汇编代码如下:

0x00000000009027e5 <+117>: xor %r9d,%r9d      <---- clear r9d, means argv6 event = 0
0x00000000009027e8 <+120>: mov 0x8,%edx       <---- absolute address, but 0x8 is in reserved segment, crash here

0x00000000009027ef <+127>: xor %r8d,%r8d
0x00000000009027f2 <+130>: mov [=13=]x3,%ecx
0x00000000009027f7 <+135>: mov [=13=]x995600,%esi
0x00000000009027fc <+140>: mov [=13=]xfd,%edi   
0x0000000000902801 <+145>: mov %ebp,0x20(%rsp)
0x0000000000902805 <+149>: mov %eax,0x18(%rsp)
0x0000000000902809 <+153>: xor %eax,%eax
0x000000000090280b <+155>: movq [=13=]x995770,0x8(%rsp)
0x0000000000902814 <+164>: mov %edx,0x10(%rsp)
0x0000000000902818 <+168>: mov [=13=]x8a,%edx
0x000000000090281d <+173>: movl [=13=]xc8e4,(%rsp)
0x0000000000902824 <+180>: callq 0x9136e0 <tesysLog>

我在汇编代码的第二行 mov 0x8,%edx 处收到信号 11,分段错误。看起来这一行是为调用 tesysLog 的 arg3(int 行)做准备。但是这里因为使用了"absolute address",而0x8在进程的地址space的保留段中,依次发出Segmentation fault.

这些代码是 运行 在 SLES 上,由 gcc 编译的。

我想知道为什么要使用 "absolute address"。是 gcc 错误,还是有影响此的编译选项?

void
tesysLog(W16 uid, char *file, int line, int level,
         W16 state, W16 event, int error, char *format, ...)

tesysLog(253, _ _FILE__, _ _LINE__, 3, 
        0, 0, result,     "error(code = %d) is %d instead of %d\n",
        header.code, decoded, size);

参数将在寄存器中:

  • rdi : W16 uid
  • rsi : 字符 *文件
  • rcx : 整行
  • rdx : 整数级别
  • r8 : W16 状态
  • r9 : W16 事件
  • 堆栈:字符 *格式,...)

你是对的,edx 是第三个参数,但是:

你必须在调用之前检查 edx 是什么,它不是 0x08 ...它是 $0x8a(第 138 行),所以“_ _LINE__”不是引起麻烦的那个,它是值存储在 (%rsp+10) 中,即 "header.code"

编辑:废话。 mode = 138, 不在线!!

0x00000000009027e8 <+120>: mov 0x8,%edx         ; here EDX is just a tmp variable
...
0x0000000000902814 <+164>: mov %edx,0x10(%rsp)  ; for THIS value!
0x0000000000902818 <+168>: mov [=11=]x8a,%edx       ; <-- THIS is edx on call

如果您公开代码,我们就能找到问题所在...我 99.9% 确定您使用的 "header.code" 是错误的 ;-)