linux下汇编语言采用的是AT&T语法,可使用GNU工具,包括汇编器gas,连接器ld,编译器gcc,调试器gdb或kdbg,objdump的反汇编功能,简档器gprof。以简单的例子分别对每个工具在汇编语言开发中的用法进行简单说明。
这些工具都要在linux环境下使用,先建立linux的开发环境,可参考文章“windows7 64位系统安装VMware Centos 64位系统搭建开发环境”。
假设有以下简单的c程序test1.c。
#include <stdio.h>
int main()
{
printf("hello, world!\n");
exit(0);
}
1. gcc用法介绍
gcc用于编译源文件,加上参数可以生成中间文件。
用gcc把test1.c编译成执行文件test1:
用gcc把test1.c编译成文件test1-g,带调试参数-g:
用gcc把test1.c生成汇编语言文件test1-s.s,用参数-S:
用gcc生成目标代码test1.o,用参数-c:
疑问:gcc带调式的参数除了-g外,还有-gstabs,-gstabs+,-ggdb和调式有关的参数,man gcc得到以下的说明。从说明中,我还是不能了解这几个参数的具体区别以及何时该用哪个,如果哪位朋友知道,请给于解释。
-g Produce debugging information in the operating system’s native format (stabs, COFF, XCOFF, or DWARF 2). GDB can work with this debugging
information.
-gstabs
Produce debugging information in stabs format (if that is supported), without GDB extensions. This is the format used by DBX on most BSD
systems. On MIPS, Alpha and System V Release 4 systems this option produces stabs debugging output which is not understood by DBX or SDB. On
System V Release 4 systems this option requires the GNU assembler.
-gstabs+
Produce debugging information in stabs format (if that is supported), using GNU extensions understood only by the GNU debugger (GDB). The use
of these extensions is likely to make other debuggers crash or refuse to read the program.
-ggdb
Produce debugging information for use by GDB. This means to use the most expressive format available (DWARF 2, stabs, or the native format if
neither of those are supported), including GDB extensions if at all possible.
汇编语言程序设计这本书是使用-gstabs这个参数。为什么不用其它参数?
最后,test1.c用这四个参数生成的的test1的大小记录如下,可见参数不一样生成的文件大小是不一样的。-g和-ggdb生成的结果大小一样。
2. objdump用于反汇编的用法
上面产生的目标文件test1.o和可执行文件test1,可使用objdump反汇编。
3. gas汇编用法
gas把汇编程序汇编成目标文件,命令是as,找到以下的汇编程序test1.s:
.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80
如下汇编,生成test1.o文件:
4. ld的用法
把前面的test1.o连接成可执行文件test1。
5. gdb和kdbg用法
gdb用的是命令方式,用惯了像VS之类的IDE调试的,感觉gdb非常不好用,尤其是对于较复杂的工程,不如kdbg好用。
从界面看,比较方便操作,不用记复杂的命令,一目了然,可以把注意力放在软件的查错上。注意编译或汇编时一定要带调试的参数,比如gcc –gstabs或者as –gstabs,否则无法调式。
kdbg需要kde和qt支持,而且在用ssh2登录linux后的secureCRT中执行会提示无法连接连接到X server,需要在启动图形界面后的,输入命令运行。
疑问:在secureCRT中怎么执行?
6. 简档器gprof用法
简档器用于分析程序中所有函数的执行时间,编译时要用-pg参数,但是查阅了帮助,as和ld都不支持-pg参数,因此只能使用gcc -pg。
用以下的test2.c为例:
/*********************************************
* test2.c
*********************************************/
#include <stdio.h>
void func1(void)
{
int i, j;
for(i=0,j=0; i<1000000; i++)
j++;
}
void func2(void)
{
int i, j;
func1();
for(i=0,j=0; i<2000000; i++)
j++;
}
int main()
{
int i;
for(i=0; i<100; i++)
func1();
for(i=0; i<200; i++)
func2();
return 0;
}
先要带参数-pg编译程序生成可执行文件test2,然后执行test2,执行一次就会生成一个新的gmon.out文件,执行gprof test2可执行文件就可以输出简档,可以重定向到test2-gprof.txt,方便查看。如下:
最后得到的test2-gprof.txt文件摘录如下:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
58.24 0.54 0.54 200 2.68 3.99 func2
42.86 0.93 0.39 300 1.31 1.31 func1
Call graph (explanation follows)
granularity: each sample hit covers 2 byte(s) for 1.08% of 0.93 seconds
index % time self children called name
<spontaneous>
[1] 100.0 0.00 0.93 main [1]
0.54 0.26 200/200 func2 [2]
0.13 0.00 100/300 func1 [3]
-----------------------------------------------
0.54 0.26 200/200 main [1]
[2] 85.9 0.54 0.26 200 func2 [2]
0.26 0.00 200/300 func1 [3]
-----------------------------------------------
0.13 0.00 100/300 main [1]
0.26 0.00 200/300 func2 [2]
[3] 42.4 0.39 0.00 300 func1 [3]
-----------------------------------------------
可以分析到func1和func2执行的时间。
%time: 表示函数占总运行时间的百分比。
cumulative seconds:表示改行及其以上的行所用的时间。
self seconds:表示函数自己本身执行的时间。
calls:函数被调用的次数。
self ms/call:函数自己每次调用所用的执行时间。不包含函数中调用的别的函数执行的时间。
total ms/call:表示函数每次调用所用的执行时间,包含调用的别的函数的时间。
name:函数名。
疑问:汇编程序.s怎么产生简档?