assembly - movsql 调用导致核心转储

标签 assembly x86-64 coredump addressing-mode

根据核心文件,首先使用where命令,然后使用disassemble命令。

(gdb) disassemble
Dump of assembler code for function prm_get_sta:
   0x0000000000414b80 <+0>:     push   %rbp
   0x0000000000414b81 <+1>:     mov    %rsi,%rbp
   0x0000000000414b84 <+4>:     push   %rbx
   0x0000000000414b85 <+5>:     mov    %rdi,%rbx
   0x0000000000414b88 <+8>:     sub    $0x18,%rsp
   0x0000000000414b8c <+12>:    movabs 0x6a53e8,%rax
   0x0000000000414b96 <+22>:    test   %rax,%rax
   0x0000000000414b99 <+25>:    je     0x414c90 <prm_get_sta+272>
   0x0000000000414b9f <+31>:    mov    0x80(%rax),%edx
   0x0000000000414ba5 <+37>:    test   %edx,%edx
   0x0000000000414ba7 <+39>:    jne    0x414c90 <prm_get_sta+272>
   0x0000000000414bad <+45>:    mov    0x8(%rbx),%edx
   0x0000000000414bb0 <+48>:    mov    0x18(%rbx),%rax
   0x0000000000414bb4 <+52>:    add    (%rbx),%rdx
   0x0000000000414bb7 <+55>:    cmp    %rdx,%rax
   0x0000000000414bba <+58>:    je     0x414ce6 <prm_get_sta+358>
   0x0000000000414bc0 <+64>:    mov    %rax,0x0(%rbp)
   0x0000000000414bc4 <+68>:    movswq (%rax),%rdx
   0x0000000000414bc8 <+72>:    movabs $0x6a2900,%rcx
=> 0x0000000000414bd2 <+82>:    movslq (%rcx,%rdx,8),%rdx
   0x0000000000414bd6 <+86>:    add    0x18(%rbx),%rdx
   0x0000000000414bda <+90>:    mov    %rdx,0x8(%rbp)

接下来,执行信息寄存器。

(gdb) info registers
rax            0x1672fa0        23539616
rbx            0x7fff6ec02f40   140735051476800
rcx            0x6a2900         6957312                 <----------------Hex to Decimal value
rdx            0xffffffffffffcccd       -13107          <----------------Hex to Decimal value 
rsi            0x7fff6ec01060   140735051468896
rdi            0x7fff6ec02f40   140735051476800
rbp            0x7fff6ec01060   0x7fff6ec01060
rsp            0x7fff6ec01000   0x7fff6ec01000
r8             0x7fff6ec02588   140735051474312
r9             0x111    273
r10            0x0      0
r11            0x2abd31653c50   46992065903696
r12            0x414b80 4279168
r13            0x7fff6ec02b00   140735051475712
r14            0x414440 4277312
r15            0x0      0
rip            0x414bd2 0x414bd2 <prm_get_sta+82>
eflags         0x10297  [ CF PF AF SF IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0

研究: movslq 命令据说可以进行 32->64 位 2 的补码符号扩展,通过将源的符号位复制到所有新的高位来进行扩展

引用括号中数据的独特用法找到了文档:(%rcx,%rdx,8),其解释如下:

(%rcx, %rdx, 8) 内存内容存储在地址 %rcx + 8%rdx*

如果正确遵循逻辑,我将其解释为使用上述注册表数据的以下含义...

(6957312 + 8*-13107)

使用运算顺序,首先执行 (8*-13107),结果为:-104,856,然后添加 6957312,即 6,852,456,并且数字足够小。

-104,856 值导致完整的 8 个字节,并且想知道那里是否可能存在问题。

问题:

1 - 这种对正在发生的情况的假设是否正确(6957312 + (8*-13107))?

2 - 乘以 8 的目的是什么?

3 - 是否有任何明显的因素会导致核心发生?

最佳答案

指令正在访问无效内存地址,原因似乎是负数组索引

正如您自己提到的,(%rcx, %rdx, 8) 访问存储在地址 %rcx + 8*%rdx 处的内存。

换句话说,我们从 8 字节元素 数组中加载一个项目,该数组从 rcx 开始,索引为 rdx

在您的情况下,rcx0x6a2900(可能是数据部分中的变量,尝试info symbol 0x6a2900)和rdx-13107 - 负数。具有负索引的索引数组在实际程序中很少发生,因此您需要查看函数的源代码并尝试了解它是如何发生的。

关于assembly - movsql 调用导致核心转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59867991/

相关文章:

gcc - 为什么 ELF 目标文件包含字符串文字和 stdlib 函数的虚拟地址?

linux - Lisp 工具包 (ltk) : Cannot get SCALE :variable value

x86-64 - 为什么 1 的补码仍然用于编码向量指令?

c++ - 在现代 x86_64 CPU 上,AVX/SSE 求幂需要多少个时钟周期?

c++ - 写入文件时核心转储?

linux - 没有相关信息的 GDB 调试跟踪(#0 0x2e6e6f69 in ?? ())

c++ - 可以在单个 CPU 指令中在 0 和 1 之间翻转位/整数/ bool 值的任何可能代码

assembly - 在 V8 中为 x64 生成 cmp 和 cmov 指令

c - 我在哪里可以找到练习 C 和汇编程序 (IA32) 的程序?

Linux - 无法生成核心转储