在x86-64 yasm程序集中运行到gdb中断点的原因不明的分段错误

我正在学习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标签后添加一个不需要的xor。

 (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 

这似乎是评论可能是正确的。 如果我正确地读取转储,则移至ebx语句将从4000b5开始,但断点设置为4000ba,这是mov指令的字节内部。

这是当我注释掉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和debugging的问题,因为评论build议。