博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编译后的汇编语言程序
阅读量:4042 次
发布时间:2019-05-24

本文共 1699 字,大约阅读时间需要 5 分钟。

们来看看由GCC 生成的汇编语言程序。程序1-1 是为检验而编写的小程序。

程序 1-1 10 次加 1 运算的程序

#include <stdio.h>
int a, b;
main()
{
    a = 0;
    do {
        b += a + 1;
        a++;
    } while (a < 11);
}

如果在编译此程序时加上-S 选项,如“gcc  -S  test.c”,就会出现如程序1-2 这样的汇编语言程序(该程序在X86 系列64 位环境下进行编译)。

程序 1-2 编译后的汇编语言程序(部分)

        .text
.globl main
        .type   main, @function
main:
.LFB2:
        pushq   %rbp
.LCFI0:
        movq    %rsp, %rbp
.LCFI1:
        movl    $0, a(%rip)     ……变量a 赋值为0
.L2:
        movl    a(%rip), %eax   ……变量a 的值放到寄存器%eax 中
        leal    1(%rax), %edx   ……(变量a)+1 的值放入%edx(%rdx 的低32 位) 中
        movl    b(%rip), %eax   ……将变量b 的值放入%eax(%rax 的低32 位)中
        leal    (%rdx,%rax), %eax  ……%rdx 和%rax 的和放入%eax 中
        movl    %eax, b(%rip)   ……%eax 的结果赋值给变量b
        movl    a(%rip), %eax   ……变量a 的值放入%eax 中
        addl    $1, %eax        ……对%eax 进行加1 运算
        movl    %eax, a(%rip)   ……%eax 的结果赋值给变量a
        movl    a(%rip), %eax   ……变量a 的值放入%eax 中
        cmpl    $10, %eax       ……将%eax 的值与10 进行比较
        jle     .L2             ……小于等于10 的话跳到L2
        leave                   ……释放栈中的变量
        ret                     ……程序跳出
.LFE2:
        .size   main, .-main
        .comm   a,4,4           ……分配给a 以4 为边界基准的4 字节内存
        .comm   b,4,4           ……分配给b 以4 为边界基准的4 字节内存
       …

大致上,左边是标签,中间是CPU 指令,右边是操作目标。以“.”开始的字符串表示指定汇序集的函数名。以“:”结束的字符行是标识符的定义。函数名和标识符以外的部分是实际被执行的指令集,与CPU 的机器语言相对应。以“%”开头的是寄存器名,以“$”开头的是常量。

“a(%rip)”表示外部变量a,“b(%rip)”表示外部变量b,外部变量引用以%rip 标识的寄存器(程序计数器标识程序接下来该执行的指令)所指的地址中相对应的位置。

从标识符.L2 到jle 指令是程序的循环部分,相当于C 语言源程序的“do~while(a<11)”。即使没有使用过汇编语言,一看到程序当中的备注也能大致理解其运行原理。

X86系列CPU的寄存器

CPU 内部有若干个高速存储单元,也就是常说的寄存器,它可以用来储存数据,还可以作为指示其储存地址的指针来使用。在下面的表格中,我们列举了 X86 系列 CPU 中常用的寄存器。

一直以来,32 位的 CPU 中所使用的寄存器为 32 位寄存器,64 位 CPU 中则使用扩展到 64 位的寄存器,更甚者追加到寄存器 r8~r15。扩展后的 64 位寄存器可以在 64 位模式下使用。

在 64 位环境中,通过使用增加的寄存器,可完成程序中函数参数的传递。rax 被用于存放返回值,rdi、rsi、rdx、rcx、r8、r9 分别用于存放第 1~6 个整数型参数。

在 32 位环境中,将函数写入栈中,这样可以缩短执行时间。另外,对部分寄存器来说,寄存器的一部分也可进行数据存储和计算操作。比如,寄存器 rax 的低 32 位是 eax,eax 的低 16 位是 ax ;ax 的高 8 位是 ah,ax 的低 8 位是 al 等。

原文地址:http://book.2cto.com/201301/13119.html

转载地址:http://zvldi.baihongyu.com/

你可能感兴趣的文章
Improved&nbsp;logging&nbsp;in&nbsp;Objective-C&nbsp;…
查看>>
ShareKit&nbsp;分享到FaceBook,&nbsp;Twitter…
查看>>
Facebook&nbsp;Share&nbsp;iOS&nbsp;Tutorial
查看>>
判断系统版本(用宏,非UIDevice)以…
查看>>
unsigned&nbsp;int的最大值及int的最大…
查看>>
Property&nbsp;List&nbsp;支持的数据类型(us…
查看>>
Shell编程基础《转》
查看>>
Xcode&nbsp;调试加入参数《Apple&nbsp;Dev&nbsp;Do…
查看>>
修改mysql编码《转》
查看>>
Posting&nbsp;images&nbsp;using&nbsp;TWRequest《…
查看>>
mac系统如何显示和隐藏文件&nbsp;《转》
查看>>
iphone开发常用代码(不断更…
查看>>
OpenCV&nbsp;学习笔记
查看>>
UIColor&nbsp;转换为&nbsp;UIImage&nbsp;《转》
查看>>
&lt;iOS4&gt;Switching&nbsp;between&nbsp;front&nbsp;an…
查看>>
opencv&nbsp;pca
查看>>
OpenCV做PCA的一个详尽的介…
查看>>
iOS&nbsp;中用代码写字体,并加入…
查看>>
《转》深入浅出&nbsp;Cocoa&nbsp;多线程编程…
查看>>
多target
查看>>