zoukankan      html  css  js  c++  java
  • 汇编语言程序设计读书笔记(1)- 相关工具

    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!
    ");
    
        exit(0);
    
    }
    

    1. gcc用法介绍

    gcc用于编译源文件,加上参数可以生成中间文件。

    用gcc把test1.c编译成执行文件test1:

    image

    用gcc把test1.c编译成文件test1-g,带调试参数-g:

    image

    用gcc把test1.c生成汇编语言文件test1-s.s,用参数-S:

    image

    用gcc生成目标代码test1.o,用参数-c:

    image

    疑问: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生成的结果大小一样。

    image

    2. objdump用于反汇编的用法

    上面产生的目标文件test1.o和可执行文件test1,可使用objdump反汇编。

    image

    image

    3. gas汇编用法

    gas把汇编程序汇编成目标文件,命令是as,找到以下的汇编程序test1.s:

    .section .text
    
    .globl _start
    
    _start:
    
        movl $1, %eax
    
        movl $0, %ebx
    
        int $0x80

    如下汇编,生成test1.o文件:

    image

    4. ld的用法

    把前面的test1.o连接成可执行文件test1。

    image

    5. gdb和kdbg用法

    gdb用的是命令方式,用惯了像VS之类的IDE调试的,感觉gdb非常不好用,尤其是对于较复杂的工程,不如kdbg好用。

    image

    从界面看,比较方便操作,不用记复杂的命令,一目了然,可以把注意力放在软件的查错上。注意编译或汇编时一定要带调试的参数,比如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,方便查看。如下:

    image

    最后得到的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怎么产生简档?

  • 相关阅读:
    GO 爬虫图片相关
    GO 爬虫链接
    Redis使用
    HTTP请求
    lris框架基础案例
    UDP通信功能
    C++随机
    matplotlib显示指数部分的负号
    使用opencv-python读取中文路径图片
    pytorch模型可视化,torchviz,tensorboardX,文本方式
  • 原文地址:https://www.cnblogs.com/kenzhang1031/p/3407630.html
Copyright © 2011-2022 走看看