プログラムの第三章マシンレベルの表現
3.1歴史観
3.2プログラム・コード
1.コマンドライン
(1)コンパイル
linux> gccの-Og -OP p1.c p2.c#コンパイラp1.cとp2.cファイル
(2)ATTフォーマットアセンブラ
linux> gccの-Og -S mytry.c#、C言語のコンパイルファイルのmytry.sを生成する直接見ることができます
linux> gccの-Og -c mytry.c#はバイナリオブジェクトコードファイルを直接見ることができない、mytry.o生成しました
Linuxの>マシンコードobjdumpの-d mytry.o#mytry.o出力ファイルおよび逆アセンブリコード、コマンドライン出力
linux> gccの-Og -o progのmain.cのmytry.c#実行ファイルPROG
Linuxの>マシンコードobjdumpの-d PROG#progの出力ファイルおよび逆アセンブリコード、コマンドライン出力
(3)インテル形式のコンパイル
linux> gccの-Og -S -masm =インテルmytry.c#が直接見ることができ、C言語のコンパイルファイルmytry.sを生成します
2. gccのコマンド処理
Cプリプロセッサ(拡張されたソースコードファイルとマクロの拡張のための#includeの#defineを挿入)
コンパイラ(.Sは、アセンブリコードのソースファイルを生成)
アセンブラ(コンパイルされたオブジェクトコードファイルにバイナリコード.o)は
リンカー(合併を実現するコードとオブジェクトコードライブラリファイル、および実行可能ファイルを生成する.P)
3.2.1マシンレベルのコード
1.抽象の2種類が
(1)命令セットアーキテクチャ/命令セット・アーキテクチャ(命令セットアーキテクチャ、ISA)
(2)仮想アドレス
3.2.2コード例
アセンブラ逆アセンブラ対1。
(1)命令長:1-15バイト
(2)多くの分解終了指示qを省略し、Qサフィックスは、呼及びRET命令に付加されます
逆アセンブルしPROG対2分解した.o
(1)異なるアドレス
所望の(2)充填解体PROG命令アドレス等callq
機能コードは16バイト、ストレージのためのコードの次のブロックとなるように(3)、NOP分解PROG端を挿入
形式上の注意事項3.2.3
行の1始まり「」:ディレクティブ、指導アセンブラとリンカの仕事
2.ATTフォーマット形式コンパイルコンパイルvsIntel
(1)インテルサイズサフィックスは省略されています
フロント(2)インテル省略レジスタ%
異なる(3)インテルの方法は、「QWORD PTR [RBX」代替「(%のRBX)」のように、メモリ位置に説明しました
代わりに、オーダー・オペランドは、(4)オペランドを有する命令の複数個所に上場します
3.3データフォーマット
サイズのx86-64で1.Cのデータ型
注意:
(1)B =バイト= 8ビット=ワード= 16ビット、L =ロングワード= 32ビット、Q =クワッドワード= 64ビットのw
(2)浮動小数点数:(?私は推測)(?)S =ショートフロート= 32ビット、L =長フロート= 64ビット
浮動小数点の完全に異なるセットを登録するため、(3)、lは4バイトの整数のいずれかを表していないと、8バイトの浮動小数点表現が、曖昧
3.4情報アクセス
1. 16整数レジスタ(非常に重要)
注意:
(1)8バイト未満の命令の結果を生成し、残りのバイトは、どのようになりますか?
上位4つのバイトを生成するために、命令の4つのバイトが2バイトの命令を生成するか、バイト残り変わらないが0に設定されています
(2)(iは推測)スタックポインタ%のRSP =レジスタ・スタック・ポインタ
動作インジケータの3.4.1数
1.数(オペランド)動作
(1)即時(即時):ATTアセンブラコードとして示され、一定の値を表し、「$」C +標準法の整数を表し、自動的に最もコンパクトな符号化方法を選択します(?)
(2)レジスタ(レジスタ):オペランドとして下位バイト1,2,4,8のためのレジスタ16、レジスタの内容を表します
(3)メモリ参照:有効なアドレスに従ってメモリ位置へのアクセス
注意:
(1)R&LT A任意レジスタAを表し、R&LT [R&LT A ]の値で表される(レジスタアレイRのセットとして考えられる、指標として識別子を登録します)
(2)Mb[Addr]表示对存储在内存中地址Addr开始的b个字节值的饮用,可省去下标b
(3)Imm(rb, ri, s)是最常用的内存引用的寻址模式,包含:立即数偏移Imm(缺省为0)、基址寄存器rb(缺省为0)、变址寄存器ri(缺省为0)、比例因子s(s=1,2,4,8,缺省为1),有效地址为Imm+R[rb]+R[ri]*s
写在前面:书中把许多不同的指令划分为指令类,每一类执行相同的操作,只不过操作数的大小不同
3.4.2 数据传送指令
1.MOV类——简单的数据传送指令:把数据从源位置复制到目的位置
格式:MOV source源操作数, destination目的操作数
注:
(1)寄存器部分的大小必须与指令做后一个字符(b、w、l、q)指定的大小相匹配
(2)S、D均可以是内存地址或寄存器,但不能同时为内存地址;从内存传送数据到内存需要两条指令:内存->寄存器,寄存器->内存
(3)movq vs movabsq: movq只能表示以表示为32位补码数字的立即数作为源操作数,然后扩展符号得到64位,而movabsq能够以任意64位立即数作为源操作数,但只能以寄存器作为目的
2.MOVZ和MOVS类:将较小的源值复制到较大的目的时使用
格式:
(1)零扩展(MOV zero)——高位补0: MOVZ+源大小+目的大小 source, register
(2)符号扩展(MOV sign)——高位扩展符号位:MOVS+源大小+目的大小 source, register
注:
(1)S可以是内存地址或寄存器,R只能是寄存器
(2)不存在movzlq指令,但可以用以32位寄存器为目的的movl指令实现,高位4字节置0
(3)cltq指令无操作数,效果与movslq %eax,%rax完全一致,但是编码更紧凑(我理解为:更省地方)
(4)一个有趣的小练习
答案: