刚开始我使用,如下命令编译,链接程序。
nasm -f elf64 -g -F stabs sandbox.asmld -o sandbox sandbox.ogdb sandbox
当我运行 sandbox 时,它会正常运行,但 gdb 无法显示任何源代码。为什么?当我在 gdb 中尝试 run 时,它不显示源代码。
;nasm -f elf64 -g -F stabs eatsyscall64.asm
;ld -o eatsyscall64 eatsyscall64.o
; ./eatsyscall64; nasm -f elf64 -g -F dwarf sandbox.asm
; ld -o sandbox sandbox.o
; gdb sandboxSECTION .dataSECTION .textglobal _start_start:nopmov eax,0mov ax,-42movsx ebx,axmov ecx,eaxnop;x86_64 通过中断(syscall)指令来实现;寄存器 rax 中存放系统调用号,同时系统调用返回值也存放在 rax 中;当系统调用参数小于等于6个时,参数则必须按顺序放到寄存器 rdi,rsi,rdx,r10,r8,r9中;当系统调用参数大于6个时,全部参数应该依次放在一块连续的内存区域里,同时在寄存器 ebx 中保存指向该内存区域的指针;当进行函数调用时,参数少于7个, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。参数为7个以上时,前 6 个与前面一样, 但后面的依次从 "右向左" 放入栈中。mov rax, 60 ;sys_exit的系统调用编号为60xor rdi, rdisyscall;mov eax, 1 ;指定exit系统调用;mov ebx, 0 ;返回0;int 80H ;80H中断,触发系统调用SECTION .bss
当我使用了 dawrf, 就可以调试了。看起来 stabs 格式不适用于 GDB。
nasm -f elf64 -g -F dwarf sandbox.asmld -o sandbox sandbox.ogdb sandbox
gdb常用指令
1. b main:在程序的main函数开始的地方设置断点;
2. b filename.c:<行号>:在文件filename.c的第<行号>行设置断点;
3. b function_name:在函数function_name的开头处设置断点;
4. b *addr:在指定内存地址addr处设置断点。
5. r:在gdb命令行输入r命令,运行程序,程序会在设置好的断点处停止;
6. n:在gdb命令行输入n命令,执行下一行代码;
7. c:在gdb命令行输入c命令,继续程序的执行;
8. bt:在gdb命令行输入bt命令,查看程序调用栈。