【问题标题】:Why does the following instruction not jump in gdb?为什么下面的指令在gdb中没有跳转?
【发布时间】:2019-04-11 02:22:28
【问题描述】:

我有以下程序,exitc.s:

[OP@localhost linking]$ cat exitc.s
    .section .text
    .globl _start

_start:
    call exit

按以下方式构建:

[OP@localhost linking]$ as exitc.s -o exitc.o
[OP@localhost linking]$ ld exitc.o -o exitc -lc -I /usr/lib64/ld-linux-x86-64.so.2 

通过gdb 运行它时,会发生以下情况:

(gdb) disas _start
Dump of assembler code for function _start:
   0x0000000000401020 <+0>: callq  0x401010 <exit@plt>
End of assembler dump.
(gdb) break *_start
Breakpoint 1 at 0x401020
(gdb) run
Starting program: /path/to/linking/exitc 

Breakpoint 1, 0x0000000000401020 in _start ()
(gdb) disas _start
Dump of assembler code for function _start:
=> 0x0000000000401020 <+0>: callq  0x401010 <exit@plt>
End of assembler dump.
(gdb) si
0x0000000000401010 in exit@plt ()
(gdb) disas 0x401010
Dump of assembler code for function exit@plt:
=> 0x0000000000401010 <+0>: jmpq   *0x2002(%rip)        # 0x403018 <exit@got.plt>
   0x0000000000401016 <+6>: pushq  $0x0
   0x000000000040101b <+11>:    jmpq   0x401000
End of assembler dump.
(gdb) si
0x0000000000401016 in exit@plt ()
(gdb) disas 0x401010
Dump of assembler code for function exit@plt:
   0x0000000000401010 <+0>: jmpq   *0x2002(%rip)        # 0x403018 <exit@got.plt>
=> 0x0000000000401016 <+6>: pushq  $0x0
   0x000000000040101b <+11>:    jmpq   0x401000
End of assembler dump.

在组装的最后一步,为什么没有发生跳转?

【问题讨论】:

  • 确实如此,但最初跳转的目标是下一条指令。
  • @Jester 不是跳跃的目标0x2002(%rip)?
  • 间接跳转。目标地址是从内存位置0x403018获取的。
  • 不,这是一个间接跳转(注意jmpq *0x2002(%rip)中的*,将其视为c间接操作符*)。
  • 哦。我什至不知道这是可能的。谢谢。有人可以写一个简单的答案,以便我可以接受并将此线程标记为完成吗?

标签: assembly x86-64 dynamic-linking


【解决方案1】:

在组装的最后一步,为什么没有发生跳转?

JUMP确实发生了,但只是碰巧跳转到下一条指令。

这完全是意料之中的,也是惰性符号解析的工作原理。您可以阅读它,例如here.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 2018-11-08
    相关资源
    最近更新 更多