> [TOC]
# x86のレジスター
## 汎用レジスタ
#### EAX
関数の戻り値や演算などの結果がよく格納される。
#### ECX
#### EDX
#### EBX
#### ESP
一時的にデータを保存できるスタックのトップのアドレスが格納されている。
スタックにはpush命令やpop命令、mov命令などでデータを格納することも可能。
#### EBP
スタックのベースのアドレスが格納されている。
#### ESI
#### EDI
## 汎用レジスタのアクセス方法
#### 32ビット
EAX、ECX、EDX、EBX
##### 使用例
###### Assembly
```
mov eax,0x11223344
mov a,eax
```
###### C言語
```
eax = 0x11223344;
a = eax;
```
#### 16ビット
AX、CX、DX、BX
##### 使用例
###### Assembly
```
mov eax,0x11223344
mov a,ax
```
###### C言語
```
eax = 0x11223344;
a = eax & 0xffff; // a = 0x3344
```
#### 8ビット(下位)
AL、CL、DL、BL
##### 使用例
###### Assembly
```
mov eax,0x11223344
mov a,al
```
###### C言語
```
eax = 0x11223344;
a = eax & 0xff; // a = 0x44
```
#### 8ビット(上位)
AH、CH、DH、BH
##### 使用例
###### Assembly
```
mov eax,0x11223344
mov a,al
```
###### C言語
```
eax = 0x11223344;
a = (eax >> 8) & 0xff; // a = 0x33
```
# x86の呼出規約
### call命令
callを使用して関数を呼び出します。
call時には戻り先(callの後に実行される命令)のアドレスがスタックに格納されます。このアドレスは基本的にret命令によってEIPが設定されます。
##### Assembly
```
push size //count
push msg //buf
push 1 //fd
call write
section .data
msg db 'seccamp', 0xa
size equ $ - msg
```
##### C言語
```
ssize_t write(int fd, const void *buf, size_t count);
char msg[] = "seccamp";
write(1,msg,sizeof(msg));
```
### ret命令
retを使用してスタックから戻り先のアドレスを取得し、EIPに設定します。
##### Assembly
```
mov eax,0
ret
```
##### C言語
```
return 0;
```
# x86のopcode(命令コード)一部
### PUSH/POP
#### PUSH
##### PUSH実行前のスタックの状態
```
---------------------
| 0x11223344 | 0xffffff48 <- ESP
|---------------------|
| 0x11223344 | 0xffffff4c
|---------------------|
| 0x11223344 | 0xffffff50
|---------------------|
| 0x11223344 | 0xffffff54
|---------------------|
```
##### PUSH実行後のスタックの状態
###### Assembly
```
mov eax,0x66774422
push eax
```
```
---------------------
| 0x66774422 | 0xffffff44 <- ESP
|---------------------|
| 0x11223344 | 0xffffff48
|---------------------|
| 0x11223344 | 0xffffff4c
|---------------------|
| 0x11223344 | 0xffffff50
|---------------------|
| 0x11223344 | 0xffffff54
|---------------------|
```
#### POP
##### POP実行前のスタックの状態
```
---------------------
| 0x77553322 | 0xffffff48 <- ESP
|---------------------|
| 0x11223344 | 0xffffff4c
|---------------------|
| 0x11223344 | 0xffffff50
|---------------------|
| 0x11223344 | 0xffffff54
|---------------------|
```
##### POP実行後のスタックの状態
###### Assembly
```
pop eax
ret // eax = 0x77553322
```
```
|---------------------|
| 0x11223344 | 0xffffff4c <- ESP
|---------------------|
| 0x11223344 | 0xffffff50
|---------------------|
| 0x11223344 | 0xffffff54
|---------------------|
```
### データ転送(mov)
##### Assembly
```
mov b,0x00000000
mov a,b
push 10
call malloc
mov c,eax
mov [c],3
mov b,[c]
mov eax,b
ret //b = 3
```
##### C言語
```
b = 0x00000000;
a = b;
*c = malloc(10);
*(int *)c = 3;
b = *(int *)c;
return b;// b = 3
```
### データ交換(xchg)
##### Assembly
```
xchg a,b
```
##### C言語
```
tmp = a;
a = b;
b = tmp;
```
### アドレス計算(lea)
##### Assembly
```
lea a,[b+1]
```
##### C言語
```
a = b+1;
```
### 加算(add)
##### Assembly
```
add b,0x11111111
add a,b
```
##### C言語
```
b = b + 0x11111111 & 0xffffffff;
a = a + b & 0xffffffff;
```
### 減算(sub)
##### Assembly
```
sub b,0x11111111
sub a,b
```
##### C言語
```
b = b - 0x11111111;
a = a - b;
```
### 乗算(mul)
##### Assembly
```
mov eax,0x99999999
mul b
```
##### C言語
```
b * 0x99999999;
```
### 除算(div)
##### Assembly
```
mov eax,0x99999999
div b
```
##### C言語
```
b / 0x99999999;
```
### インクリメント(inc)
##### Assembly
```
inc a
```
##### C言語
```
a++;
```
### デクリメント(dec)
##### Assembly
```
dec a
```
##### C言語
```
a--;
```
### 排他的論理和(xor)
##### Assembly
```
sub b,0x11111111
sub a,b
```
##### C言語
```
b = b - 0x11111111;
a = a - b;
```
### 論理積(and)
##### Assembly
```
and a,b
```
##### C言語
```
a = a && b;
```
### 論理和(or)
##### Assembly
```
or a,b
```
##### C言語
```
a = a || b;
```
### 否定(not)
##### Assembly
```
not b
```
##### C言語
```
b = !b;
```
### 算術シフト(sal/sar)
##### Assembly
```
mov a,1
sal a,4
```
##### C言語
```
a = 1;
a = a * 16
```
### ビットシフト(shl/shr)
##### Assembly
```
mov a,1
shl a,3
```
##### C言語
```
a = 1;
a = a << 3
```
### 比較
#### test
##### Assembly
```
mov a,0
test a,a
jnz goto
mov a,1
goto:
ret // a = 1
```
##### C言語
```
a = 0;
if(a == 0){
a = 1;
}
return a; // a = 1
```
#### cmp
##### Assembly
```
mov a,0
cmp a,0
jnz goto
mov a,1
goto:
ret // a = 1
```
##### C言語
```
a = 0;
if(a == 0){
a = 1;
}
return a; // a = 1
```
### 分岐
分岐の命令では、基本的には以下の条件が適用される。
・命令にNがついた場合条件を否定(not)
・命令にEがついた場合同等(equal)
#### jz(ゼロである場合)
#### jmp(無条件)
#### JB(対象より下の場合)
#### JL(対象より小さい場合)
#### JG(対象より大きい場合)
#### ja(対象より上の場合)