全身心理解程序的转换过程

> 计算机的指令分类:

伪指令:机器指令序列
机器指令:机器指令和汇编指令一一对应
汇编指令:机器指令的汇编语言
微指令:微程序级指令,属于硬件范畴,这点组成原理上有讲过。

其中汇编指令和机器指令都属于机器级指令。
启发:
汇编在转换为机器指令时并没有进行优化,相同的汇编程序在执行时带来的效率差 别应该源于硬件的不同。
ISA(指令级体系结构) 的存在使得汇编更方便移植。
在此可见ISA在整个计算机系统抽象层中的重要性。


> 生成机器代码的过程:

用 GCC + Linux + IA32 平台进行实验

程序转换四个步骤:
1. 预处理
引入#include<文件>和处理宏语句
2. 编译
将处理后的源程序文件编译成相应的 汇编语言程序
3. 汇编
将汇编源程序文件转换为可重定位的 机器语言目标代码文件
4. 链接
由连接器将多个可重定位的机机器语言目标程序文件以及库例程连接起来,得到 可执行文件

> 这里以hello.cpp为例

-第一步
> gcc -E hello.cpp -o hello.i
因为引入了<iostream>输入输出流文件,所以.......预处理后特别长
hello.i 大小:411KB



注意到了吗?在这里我用gcc对c++源文件进行预处理居然也是可以的。

好奇提问:GCC 对于 c 和 cpp 的预处理操作是相同的吗? gcc -E
加一条指令:g++ -E hello.cpp -o hello++.i
从实验结果上:
GCC 对于cpp的预处理跟G++效果相同。但后续就完全不同了。

-第二步
> g++ -S hello.i -o hello.s
得到的汇编指令有80行
hello.s 大小:2KB

-第三步
> g++ -c hello.s -o hello.o
目标程序 hello.o 有3KB (这里只生成了一个目标文件)

-第四步
> g++ hello.o -o hello
执行程序大小: 9KB


-执行吧!!
./hello
Hola!

------正文完------

附录:

g++ manual 摘录:
-E Stop after the preprocessing stage; do not run the compiler
proper. The output is in the form of preprocessed source code,
which is sent to the standard output.

Input files that don't require preprocessing are ignored.

-c Compile or assemble the source files, but do not link. The
linking stage simply is not done. The ultimate output is in the
form of an object file for each source file.

By default, the object file name for a source file is made by
replacing the suffix .c, .i, .s, etc., with .o.

Unrecognized input files, not requiring compilation or assembly,
are ignored.

-S Stop after the stage of compilation proper; do not assemble. The
output is in the form of an assembler code file for each non-
assembler input file specified.

By default, the assembler file name for a source file is made by
replacing the suffix .c, .i, etc., with .s.

Input files that don't require compilation are ignored.
-o file
Place output in file file. This applies to whatever sort of
output is being produced, whether it be an executable file, an
object file, an assembler file or preprocessed C code.

If -o is not specified, the default is to put an executable file
in a.out, the object file for source.suffix in source.o, its
assembler file in source.s, a precompiled header file in
source.suffix.gch, and all preprocessed C source on standard
output.
更多关于gcc/g++的使用请自行查询

hello.cpp 源文件
# include<iostream>
using namespace std;

int main()
{
cout<<"Hola!"
}


(正向编译)汇编指令源程序(AT&T格式):
.file "hello.cpp"
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.section .rodata
.LC0:
.string "Hola!"
.text
.globl main
.type main, @function
main:
.LFB971:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE971:
.size main, .-main
.type _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB975:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
cmpl $1, -4(%rbp)
jne .L3
cmpl $65535, -8(%rbp)
jne .L3
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
call __cxa_atexit
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE975:
.size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.type _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB976:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $65535, %esi
movl $1, %edi
call _Z41__static_initialization_and_destruction_0ii
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE976:
.size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I_main
.hidden __dso_handle
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值