本文主要介绍了对Nasm汇编代码进行调试要如何编译,以及在调试过程中的会用到的一些基础指令。
1. 示例代码
section .data
message db "hello, nasm!", 0ah
msgLen equ $-message
section .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, message
mov edx, msgLen
int 80h
mov eax, 1
mov ebx, 0
int 80h
2. 调试编译
2.1 通过ld
命令链接
在编译和链接的时候要带上-g
参数,如下:
nasm -felf32 -g hello.asm -o hello.o
ld -g -melf_i386 hello.o -o hello
这样编译后就有调试信息了。
2.2 通过gcc
命令链接
网上有很多教程(包括官网)都是通过gcc做的链接,但如果你是在64位机器下,要注意nasm带上-felf32
,gcc带上-m32
参数,并且hello.asm汇编文件global指定的名称一定要是main。
编译命令如下:
nasm -felf32 -l hello.lst hello.asm
gcc -m32 -g hello.o -o hello
源文件修改:
section .text
global main
main:
mov eax, 4
这两种方式都能实现编译调试的功能,但感觉使用ld命令生成的汇编码更贴进自已编写的源码,调试起来也更方便。
3. 调试
在调试的时候最主要是用到四个命令,如下:
ni
:执行下一个指令
si
:跳入当前函数(函数是指call调用的位置)
disas
:显示当前执行到哪个汇编指令了。
r
:显示当前所有寄存器的值。
3.1 调试命令 disas
这个指令可以很清楚的看到下个即将执行的汇编指令,但这个是AT&T风格的汇编,赋值是从左住右,如下:
(gdb) disas
Dump of assembler code for function _start:
0x08048080 <+0>: mov $0x4,%eax
=> 0x08048085 <+5>: mov $0x1,%ebx
0x0804808a <+10>: mov $0x80490a4,%ecx
0x0804808f <+15>: mov $0xd,%edx
0x08048094 <+20>: int $0x80
0x08048096 <+22>: mov $0x1,%eax
0x0804809b <+27>: mov $0x0,%ebx
0x080480a0 <+32>: int $0x80
End of assembler dump.
=>
指示的就是当前正在执行的行。
如果想换成Intel风格的汇编,可以使用如下命令:
set disassembly-flavor intel
3.2 调示命令 r
(gdb) info r
eax 0x4 4
ecx 0x0 0
edx 0x0 0
ebx 0x0 0
esp 0xffffd000 0xffffd000
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x8048085 0x8048085 <_start+5>
eflags 0x202 [ IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
有时候只想看某个寄存器的值,可以用print
调试命令,如下:
print/x $eax ; 查看寄存器eax的值