https://github.com/bootjp/hello_assembly_world
https://github.com/bootjp/hello_assembly_world
Last synced: over 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/bootjp/hello_assembly_world
- Owner: bootjp
- Created: 2017-12-31T09:06:50.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-07-22T07:05:55.000Z (almost 8 years ago)
- Last Synced: 2025-01-03T23:28:13.846Z (over 1 year ago)
- Language: Assembly
- Size: 12.7 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# assembly study
## nasm
```bash
brew install nasm
nasm -v
> NASM version 2.13.02 compiled on Nov 30 2017
nasm -f macho64 -o sample.o scratch.asm && ld -o sample.out sample.o && ./sample.out
```
## masm
base document: http://wisdom.sakura.ne.jp/programming/asm/index.html
current : http://wisdom.sakura.ne.jp/programming/asm/assembly8.html
use DOSBox
+ https://www.dosbox.com/
+ 8086 Assembler
* ToDo
+ [ ] DOSBox change keyboard layout
+ [official documents](https://www.dosbox.com/DOSBoxManual.html#KeyboardLayout)
+ [question](https://superuser.com/questions/1080381/keyboard-layout-setting-in-dosbox-has-no-effect)
+ [ ] DOSBox build for high Sierra
* japanese keyboard layout = 106
* dosbox howt to use.
```dos
mount c ~/dosbox # ~/doxbosはosx環境上
c:\
debug
```
## study
### レジスタ
* 汎用レジスタ (何に使ってもよい、Ex 変数)
+ AX アキュムレータ
+ BX ベースレジ
+ CX カウントレジスタ (ループなどのカウンタに使いことが多い)
+ DX データレジスタ
* インデックスレジスタ
+ SI ソースインデックス
+ DI ディスティネーションインデックス
* 特殊レジスタ
+ BP ベースポインタ
+ SP スタックポインタ
+ IP イントラクションポインタ
* セグメントレジスタ
+ CS コードセグメント
+ DS データセグメント
+ ES エクストラセグメント
+ SS スタックセグメント
### 汎用レジスタについて
+ 汎用レジスタは16ビットで構成される場合、8ビットを二つ組み合わせている
+ AXレジスタの実体は8ビットのAHとALレジスタの二つが実体
+ AHはAXの上位8ビット (High)
+ ALはAXの上位8ビット (Low)
+ 同様にBX, CX, DXの汎用レジスタは8ビット毎に分割されている
+ 不明点: 今は16ビットなので High Lowだけど32, 64だと?
+ 64ビットでは上位概念としてEAXレジスタがあり、EXレジスターをラップするRAXレジスタというものがあるようだ。
+ 64ビットではAXレジスタは4つ存在し、AXレジスタを管理する(?)EAXレジスタがあり
+ EAX レジスタも二つあり、EAXレジスタを管理する(?) RAXレジスタがある
+ ref: http://www.mztn.org/lxasm64/amd04.html
### 命令形
* MOV (レジスタ|メモリ)へのデータ転送
+ 高級言語でいう代入
* 第一オペランドがdest(値を転送される側、保存対象領域を指定する)
* 第二オペランドがsource(代入を行う(レジスタ、メモリアドレス、数値))
+ 非破壊読み取りである。データ代入しても元の領域の値は壊れない(いわゆる参照渡しではない?)
* ニーモニックというものの一つに分類される(?)
### リトルエンディアン
```
-A 100 103
MOV AX, 1234
-G=100 103
AX=1234...(略
```
これを逆アセンブルして見てみると
```
-U 100 103
073F:0100 B83412 MOV AX, 1234
073F:0103 0000 ADD [BX+SI],AL
```
となっている8086命令形ではリトル・エンディアンマシンというらしく、
ワードのバイトは下位から順にアドレスが割り当てられる。
注意すべきはバイト毎に割り当てるということであり、単純に `4321` とはならない `3412` となる。
### 8086のアドレスについて
* アセンブリであっても物理アドレスへのアクセスの指定はできない
* セグメント方式が採用されている
* セグメントに対してオフセットがある
+ これらを計算することで物理アドレスを導き出すことができる
* これらをセグメントベースという
* セグメントベースは16進数の5桁で表されるため0-f * 5 = 1MB
* オフセットアドレスは4桁16進数 = 64KB
### セグメントレジスタ
* セグメントレジスタはセグメントアドレスを指定するのに用いられる
* メモリアクセス時コンピュータはセグメントレジスタ経由で参照をする
* セグメントレジスタは合計4つ存在しそれぞれに専用の役割が存在する(64bitでは?)
* セグメントレジスタはCS(コード), DS(データ), ES(エクストラ), SS(スタック)の4つがあり,CSではコード・レジスタとなる
* CSレジスタは自分自身のセグメントレジスタを指す
- 実行中の機械語を格納しているアドレスである
- CPUが機械語を実行する際に使う
* DSレジスタはデータを格納する専用のセグメントを指す
* ESレジスタはDSレジスタのようなものでデータ以外にセグメントが必要なときに使う
* SSレジスタはスタック操作に使用する
### アドレッシング
+ メモリとのデータの転送
* オフセットアドレス(絶対アドレスではなく相対値)で指定する
* オフセットアドレスで指定する場合は `[]` で囲う必要がある
```
MOV AX, [0200]
MOV [0200] , AX
```
* アセンブリでは他の記憶媒体からデータを読み込む際は「ロード」と言う
* レジスタからメモリへデータを転送することを「ストア」と言う
* ちなみにメモリから他の記録媒体に保存することを「セーブ」と言う
* 同一の記録媒体の別アドレスへデータを移すときは「転送」という
* 以下はメモリとレジスタ間のデータ転送をしている
```
-A 100
073F:0100 MOV AX , 4142
073F:0103 MOV [0200] , AX
073F:0106
-G =100 106
AX=4142 BX=0000 CX=0000 DX=0000 SP=00FD BP=0000 SI=0000 DI=0000
DS=073F ES=073F SS=073F CS=073F IP=0106 NV UP EI PL NZ NA PO NC
073F:0106 0000 ADD [BX+SI],AL
-D 200 201
073F:0200 42 41 BA
```
* 以下のように右オペランドにオフセットアドレスを指定することも可能
```
073F:0100 MOV AX, 4142
073F:0103 MOV [0200], AX
073F:0106 MOV DX, [0200]
073F:010A
```
+ 即値のストア
* メモリへ即値(レジスタ経由でない)をストアする場合にはデータのサイズ指定が必要である
- レジスタのときに必要がないのはレジスタのサイズが決まっていることと
- メモリは1バイトでも1ワードでもストア可能なため(ワードってなんだ?)
* そこで明示的に指定する方法として `PTR` 演算子を使用する
* この演算子はアセンブラにサイズを知らせるためのもの
* `SIZE PTR`
* SIZEの部分にはBYTEまたはWORDを指定する(32bitではDWORDもある(64bitは?))
* BYTEを指定した場合は1バイト,WORDを指定した場合は2バイト(16bit)を確保する
* 構文の仕様はアセンブラによって異なるが,一般的に左辺のオペランドの前に指定する
* `MOV BYTE PTR ...`
* ほとんどのアセンブラではメモリに即値をストアする場合に指定しなければならない
```
-A 100
073F:0100 MOV BYTE PTR [0200] , 41
073F:0105 MOV WORD PTR [0300] , 4342
073F:010B
```
```
-D 200 200
073F:0200 42 #<= なんかおかしい
-D 300 301
073F:0300 00 00 #<= なんかおかしい
```
+ アドレッシングモード
* データの転送左辺と右辺のオペランドは機械語で一意である必要がある
+ `MOV AX, FF` と `MOV AX, [0200]`では別物である
+ アセンブラは左辺と右辺のタイプ(レジスタ|メモリ|即値)で機械語を決めている
+ つまり以下は成立しない
* `MOV [0200], [0300]`
+ これに対応する機械語が存在しないため実行できない
+ アセンブラではレジスタ,メモリ,即値のうち転送可能な組み合わせが決まっている
- さらにレジスタでも使えるものとそうでないものがある
* 転送可能な組み合わせ
+ 即値 -> レジスタ
+ 即値 -> メモリ(オフセット)
+ メモリ(オフセット) <-> レジスタ
+ レジスタ <-> セグメントレジスタ
+ セグメントレジスタ <-> メモリ(オフセット)
* フラグレジスタは特殊なレジスタのため一切の転送が行えない