分类: LINUX
2012-05-23 12:18:46
NASM 是一个为可移植性与模块化而设计的一个 80x86 的汇编器,即网际汇编。它支持相当多的目标文件格式,包括 Linux 和'NetBSD/FreeBSD','a.out','ELF','COFF',微软 16位的'OBJ'和'Win32'。它还可以输出纯二进制文件。它的语法设计得相当的简洁易懂,和masm语法很相似,如果你熟悉masm格式汇编的话,你会很容易上手的。如果你需要了解它的语法和用法,请参阅nasm中文手册。
nasm -f
下面是几种常用的命令:
生成elf格式的目标文件命令: nasm -f elf test.asm
生成二进制文件: nasm test.asm -o test.bin
生成.com文件: nasm test.asm -o test.com
生成可用于gdb调试的文件:nasm -f elf test.asm -g -F stabs
下面两行命令将使得nasm格式汇编可以在gdb中调试。
nasm -f elf test.asm -l test.lst -g -F stabs
gcc -g -o test test.o
注释:-f elf 设定输出文件为linux下的elf格式
-g 激活调试信息
-F stabs 说明生成调试信息的格式
-l test.lst 生成一个.lst文件,里面包含源代码以及地址等信息,可以帮助你查看错误
下面是我的调试过程:
lishuo@lishuo-Rev-1-0:~$ gdb test
GNU gdb (Ubuntu/Linaro 7.4-2012.02-0ubuntu2) 7.4-2012.02
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<
Reading symbols from /home/lishuo/test...done.
(gdb) list <=======================列出源代码
1
2 ; test.asm
3 ;
4 ; assemble: nasm -f elf -l hello.lst hello.asm -g -F stabs
5 ; link: gcc -g -o hello hello.o
6 ; run: ./test
7 ; output is: This Is A Test !
8
9 SECTION .data ; 这里存放数据
10 msg: db "This Is A Test !",10
(gdb) <======================= 回车接着执行list命令
11 len: equ $-msg
12
13
14 SECTION .text ; 这是代码段
15
16 global main ; 导出main可以让链接器识别
17 main:
18
19 mov edx,len ; 显示字符串的长度
20 mov ecx,msg ; 字符串的地址
(gdb)
21 mov ebx,1
22 mov eax,4
23 int 0x80
24
25 mov ebx,0
26 mov eax,1
27 int 0x80
(gdb) b 17 <========================break的简写,设置断点,在源代码的17行
Breakpoint 1 at 0x80483c0: file test.asm, line 17.
(gdb) b 20
Breakpoint 2 at 0x80483c5: file test.asm, line 20.
(gdb) b 21
Breakpoint 3 at 0x80483ca: file test.asm, line 21.
(gdb) b 22
Breakpoint 4 at 0x80483cf: file test.asm, line 22.
(gdb) b 25
Breakpoint 5 at 0x80483d6: file test.asm, line 25.
(gdb) b main <========================在函数main处设置断点
Note: breakpoint 1 also set at pc 0x80483c0.
Breakpoint 6 at 0x80483c0
(gdb) b 24
Note: breakpoint 5 also set at pc 0x80483d6.
Breakpoint 7 at 0x80483d6: file test.asm, line 24.
(gdb) info b <========================显示断点信息
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483c0 test.asm:17
2 breakpoint keep y 0x080483c5 test.asm:20
3 breakpoint keep y 0x080483ca test.asm:21
4 breakpoint keep y 0x080483cf test.asm:22
5 breakpoint keep y 0x080483d6 test.asm:25
6 breakpoint keep y 0x080483c0
7 breakpoint keep y 0x080483d6 test.asm:24
(gdb) delete 6 <======================删除断点6
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483c0 test.asm:17
2 breakpoint keep y 0x080483c5 test.asm:20
3 breakpoint keep y 0x080483ca test.asm:21
4 breakpoint keep y 0x080483cf test.asm:22
5 breakpoint keep y 0x080483d6 test.asm:25
7 breakpoint keep y 0x080483d6 test.asm:24
(gdb) r <=========================开始执行,调试开始
Starting program: /home/lishuo/test
Breakpoint 1, 0x080483c0 in main ()
(gdb) n <====================由于nasm的一些原因,单步执行n和s都不能使用
Single stepping until exit from function main,
which has no line number information.
Breakpoint 2, 0x080483c5 in main ()
(gdb) s
Single stepping until exit from function main,
which has no line number information.
Breakpoint 3, 0x080483ca in main ()
(gdb) print $eax <=======================打印寄存器的值
$1 = 1
(gdb) info r <==========================显示所有的寄存器值
eax 0x1 1
ecx 0x804a010 134520848
edx 0x11 17
ebx 0xb7fc2ff4 -1208209420
esp 0xbffff2fc 0xbffff2fc
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x80483ca 0x80483ca
eflags 0x200246 [ PF ZF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) disassemble <========================反汇编
Dump of assembler code for function main:
0x080483c0 <+0>: mov $0x11,%edx
0x080483c5 <+5>: mov $0x804a010,%ecx
=> 0x080483ca <+10>: mov $0x1,%ebx
0x080483cf <+15>: mov $0x4,%eax
0x080483d4 <+20>: int $0x80
0x080483d6 <+22>: mov $0x0,%ebx
0x080483db <+27>: mov $0x1,%eax
0x080483e0 <+32>: int $0x80
0x080483e2 <+34>: nop
0x080483e3 <+35>: nop
0x080483e4 <+36>: nop
0x080483e5 <+37>: nop
0x080483e6 <+38>: nop
0x080483e7 <+39>: nop
0x080483e8 <+40>: nop
0x080483e9 <+41>: nop
0x080483ea <+42>: nop
0x080483eb <+43>: nop
0x080483ec <+44>: nop
0x080483ed <+45>: nop
0x080483ee <+46>: nop
0x080483ef <+47>: nop
---Type
End of assembler dump.
(gdb) x/5cb 0x804a010 <================显示内存地址0x804a010开始的一段内存的值
0x804a010
(gdb) set disassembly-flavor intel <==========设置以intel汇编形式显示
(gdb) disassemble main
Dump of assembler code for function main:
0x080483c0 <+0>: mov edx,0x11
0x080483c5 <+5>: mov ecx,0x804a010
=> 0x080483ca <+10>: mov ebx,0x1
0x080483cf <+15>: mov eax,0x4
0x080483d4 <+20>: int 0x80
0x080483d6 <+22>: mov ebx,0x0
0x080483db <+27>: mov eax,0x1
0x080483e0 <+32>: int 0x80
0x080483e2 <+34>: nop
0x080483e3 <+35>: nop
0x080483e4 <+36>: nop
0x080483e5 <+37>: nop
0x080483e6 <+38>: nop
0x080483e7 <+39>: nop
0x080483e8 <+40>: nop
0x080483e9 <+41>: nop
0x080483ea <+42>: nop
0x080483eb <+43>: nop
0x080483ec <+44>: nop
0x080483ed <+45>: nop
0x080483ee <+46>: nop
0x080483ef <+47>: nop
---Type
End of assembler dump.
(gdb) x/90xb main <===============显示main开始的内存的内容
0x80483c0
0x80483c8
0x80483d0
0x80483d8
0x80483e0
0x80483e8
0x80483f0 <__libc_csu_init>: 0x55 0x57 0x56 0x53 0xe8 0x69 0x00 0x00
0x80483f8 <__libc_csu_init+8>: 0x00 0x81 0xc3 0xfb 0x1b 0x00 0x00 0x83
0x8048400 <__libc_csu_init+16>: 0xec 0x1c 0x8b 0x6c 0x24 0x30 0x8d 0xbb
0x8048408 <__libc_csu_init+24>: 0x20 0xff 0xff 0xff 0xe8 0x83 0xfe 0xff
0x8048410 <__libc_csu_init+32>: 0xff 0x8d 0x83 0x20 0xff 0xff 0xff 0x29
0x8048418 <__libc_csu_init+40>: 0xc7 0xc1
(gdb) info stack <=========================显示堆栈信息
#0 0x080483ca in main ()
(gdb) q <====================退出正在调试的程序
A debugging session is active.
Inferior 1 [process 2587] will be killed.
Quit anyway? (y or n) n
Not confirmed.
(gdb) c <==============继续调试到下一个断点
Continuing.
Breakpoint 4, 0x080483cf in main ()
(gdb) c
Continuing.
This Is A Test !
Breakpoint 5, 0x080483d6 in main ()
(gdb) c
Continuing.
[Inferior 1 (process 2587) exited normally]
(gdb) q <==================退出gdb调试