3

我正在 Oracle Enterprise Linux 7.3 VM 上学习 x86-64 程序集。我有一个简单的程序,它在 gdb 之外运行良好,但如果我设置断点并运行程序,则会出现分段错误。我已经将它缩减为一个非常小的程序,但想知道我是否做错了什么,或者它是否只是一个 gdb 错误。这是文件 ex1.asm 的源代码:

       segment .data
a      dd 1
       segment .text
       global _start
_start:
       mov eax,4
ltop:
       mov ebx,[a]
; exit with return code 0
       mov eax,60
       mov edi,0
       syscall
       end

我像这样组装、链接它并在 gdb 中运行它:

 yasm -f elf64 -g dwarf2 -l ex1.lst ex1.asm; ld -o ex1.exe ex1.o; gdb ex1.exe

以下是 gdb 会话的运行方式:

(gdb) l
1              segment .data
2       a      dd 1
3              segment .text
4              global _start
5       _start:
6              mov eax,4
7       ltop:
8              mov ebx,[a]
9       ; exit with return code 0
10             mov eax,60
(gdb) b 8
Breakpoint 1 at 0x4000ba: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe

Program received signal SIGSEGV, Segmentation fault.
ltop () at ex1.asm:6
6              mov eax,4

我有一个简单的解决方法。我只是在 _start 标签之后添加了一个不需要的异或。

(gdb) l
1              segment .data
2       a      dd 1
3              segment .text
4              global _start
5       _start:
6              xor eax,eax
7              mov eax,4
8       ltop:
9              mov ebx,[a]
10      ; exit with return code 0
(gdb) b 9
Breakpoint 1 at 0x4000b7: file ex1.asm, line 9.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe

Breakpoint 1, ltop () at ex1.asm:9
9              mov ebx,[a]

删除 ltop 标签也可以,但是我为这个示例缩减的较大的原始程序需要该标签,所以这不是一个很好的解决方法。

(gdb) l
1              segment .data
2       a      dd 1
3              segment .text
4              global _start
5       _start:
6              mov eax,4
7       ;ltop:
8              mov ebx,[a]
9       ; exit with return code 0
10             mov eax,60
(gdb) b 8
Breakpoint 1 at 0x4000b5: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe

Breakpoint 1, _start () at ex1.asm:8
8              mov ebx,[a]

有点奇怪。也许有一些明显的我做错了,但它看起来更像是一个 gdb 错误。

谢谢,鲍比

基于评论的附加信息:

(gdb) l
1              segment .data
2       a      dd 1
3              segment .text
4              global _start
5       _start:
6              mov eax,4
7       ltop:
8              mov ebx,[a]
9       ; exit with return code 0
10             mov eax,60
(gdb) b 8
Breakpoint 1 at 0x4000ba: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe

Program received signal SIGSEGV, Segmentation fault.
ltop () at ex1.asm:6
6              mov eax,4
(gdb) q
A debugging session is active.

        Inferior 1 [process 4184] will be killed.

Quit anyway? (y or n) y
[bobby@assembly gdbbug]$ objdump -D ex1.exe

ex1.exe:     file format elf64-x86-64


Disassembly of section .text:

00000000004000b0 <_start>:
  4000b0:       b8 04 00 00 00          mov    $0x4,%eax

00000000004000b5 <ltop>:
  4000b5:       8b 1c 25 c8 00 60 00    mov    0x6000c8,%ebx
  4000bc:       b8 3c 00 00 00          mov    $0x3c,%eax
  4000c1:       bf 00 00 00 00          mov    $0x0,%edi
  4000c6:       0f 05                   syscall

看来评论可能是正确的。如果我正确读取转储,则 move to ebx 语句从 4000b5 开始,但断点设置在 mov 指令字节内的 4000ba 处。

这就是我注释掉 ltop 标签时发生的情况:

(gdb) b 8
Breakpoint 1 at 0x4000b5: file ex1.asm, line 8.
(gdb) r
Starting program: /home/bobby/gdbbug/ex1.exe

Breakpoint 1, _start () at ex1.asm:8
8              mov ebx,[a]

断点位于转储中的 0x4000b5 处:

00000000004000b0 <_start>:
  4000b0:       b8 04 00 00 00          mov    $0x4,%eax
  4000b5:       8b 1c 25 c8 00 60 00    mov    0x6000c8,%ebx

谢谢回复。

我使用 nasm 使用此命令行重新进行了此操作:

nasm -f elf64 ex1.asm -o ex1.o -l ex1.lst -g -F dwarf; ld -o ex1.exe ex1.o; gdb ex1.exe

它工作得很好。因此,正如评论所建议的,这似乎是 yasm 和调试的问题。

4

0 回答 0