通訳の準備コードのコンパイル
各レジスタの目的を理解します
アセンブリコードの解釈(ソースコードを見ずに)
multstore: pushq%RBX //%RBX発信者がに格納された値を関数multstoreは、他の関数によって呼び出されるので、レジスタを保存し、したがってあるスタック%RBX %のRDXを移動%RBX //%RDXは、発信者節約RBXである%レジスタであるmult2の実行%のRDXの値の間にそれを確実にするために、レジスタ値%のRDXの%RBXが配置されている呼び出し先保存どこかはレジスタまたはメモリに保存されています // mult2を呼び出す関数mult2を呼び出し、プロセスmult2に制御を転送します %のRAX、(%のRBX)を移動//位置のmult2%RBX(格納アドレス)への戻り値が指さ popq%RBX //とpushq%RBXは%RBXの値を復元するために対応します 右
対応するソース
長いmult2(長い長いです)。 ボイドmultstore(長いX、Y長い、長い* DEST){ 長いT = mult2(X、Y) * DEST = T; }
ツール:GCC
コマンドライン:Linuxの>のgcc -c -Og mstore.c
Linuxの> Linuxの端末環境を表し、-Og、-c、およびmstore.o GCCプログラム渡さ三つのパラメータ、GCCコンパイラ、アセンブラ・ソース・コードに変換することができるプログラムは、その後、マシンコードに変換されますそれはmstore.c mstore.oソースコードファイルはマシンコードファイルにコンパイルされることを示します
機械コード・プログラムは、機械によって実行されるが、バイトのシーケンスは、マシンコードの生成は、そのソースの無知です
マシンコードmstore.o 53 48 89 D3 E8 00 00 00 00 48 89 03 5B C3
ツール:逆アセンブラプログラム
クラスにマッピングされたマシンコードのアセンブラコード
コマンドライン:Linuxの> objdumpの-d mstore.o
linux>表示在linux的终端环境下;objdump表示运行名为objdump的可执行程序;-d和mstore.o为传入objdump程序的两个参数,表示对目标代码文件mstore.o进行反汇编
0000000000000000 <multstore>: 0: 53 push %rbx 1: 48 89 d3 mov %rdx,%rbx 4: e8 00 00 00 00 callq 9 <multstore+0x9>(?) 9: 48 89 03 mov %rax,(%rbx) c: 5b pop %rbx d: c3 retq
关于机器代码和反汇编的特性
x86-64的指令从1~15个字节不等。常用的指令以及操作数较少的指令所需的字节数较少,那些不太常用或字节数较多的指令所需字节数较多
设计指令格式的方式是,从某个置顶位置开始,可以将字节唯一地解码成机器指令。例如只有pushq %rbx一条指令是53开头的
生成可执行代码需要对一组目标代码文件运行链接器,而这一组目标代码中必须有一个main函数
命令行:linux> gcc -Og -o prog main.c mstore.c
linux>表示在linux的终端环境下;gcc也具有链接的功能;-Og,-o,prog,main.c和mstore.c为传入gcc程序的五个参数,表示将main.c源文件和mstore.c源文件编译并链接成可执行文件prog(变成了8655字节!远远多于14字节!原因是链接时包含了用来启动终止程序的代码,以及用来与操作系统交互的代码)
下面是prog文件的一小段代码
0000000000400540 400540:53 push %rbx 400541:48 89 d3 move %rdx,%rbx 400544:e8 42 00 00 00 calls 40058b <mult2> 400549:48 89 03 mov %rax,(%rbx) 40054c:5b pop %rbx 40054d:c3 retq 40054e:90 nop 40054f:90 nop
与mstore.c反汇编产生的代码几乎一样
区别有:
左侧地址不同,原因是链接器将这段代码的地址移到了一段不同的地址范围里
链接器填上了callq指令调用函数mult2所需的地址,原因是链接器的任务之一是为函数调用找到可执行代码的位置
多了两行代码:为了使函数代码变为16字节