# 4.4 程序的机器级代码

## 4.4.1 x86汇编指令

### 一、指令格式

> 指令 目的操作数 源操作数

mov <mark style="color:blue;">eax</mark>, <mark style="color:blue;">ebx</mark>

将<mark style="color:blue;">寄存器ebx</mark>的值复制到<mark style="color:blue;">寄存器eax</mark>

mov <mark style="color:blue;">eax</mark>, <mark style="color:purple;">5</mark>

将<mark style="color:purple;">立即数5</mark>的值复制到<mark style="color:blue;">寄存器eax</mark>

mov <mark style="color:blue;">eax</mark>, <mark style="color:red;">dword ptr</mark> <mark style="color:green;">\[af996h]</mark>

将<mark style="color:green;">内存地址\[af996h]</mark>所指的<mark style="color:red;">32bit</mark>值复制到<mark style="color:blue;">寄存器eax</mark>

mov <mark style="color:red;">byte ptr</mark> <mark style="color:green;">\[af996h]</mark>, <mark style="color:purple;">5</mark>

将<mark style="color:purple;">立即数5</mark>的值复制到<mark style="color:green;">内存地址\[af996h]</mark>所指的<mark style="color:red;">一字节</mark>中

{% hint style="success" %}
指明内存读写的长度

* **dword ptr**：双字，32bit
* **word ptr**：单字，16bit
* **byte ptr**：字节，8bit

主存没有指令长度<mark style="color:orange;">**默认32bit**</mark>
{% endhint %}

### 二、常用寄存器

E：(Extended)，32bit

* **通用寄存器**（X：未知）
  * EAX：作为累加器
  * EBX：作为基地址寄存器
  * ECX：作为循环计数器
  * EDX：作为数据寄存器

{% hint style="info" %}
通用寄存器可以继续细分为16bit和8bit的

<img src="/files/aP8zz8Fh7qFn5VeQ5D2Z" alt="" data-size="original">
{% endhint %}

* **变址寄存器**（I：Index）
  * ESI：（Source）源操作数
  * EDI：（Destination）目的操作数
* **堆栈寄存器**
  * EBP：（Base Pointer）堆栈基指针
  * ESP：（Stack Pointer）堆栈顶指针

### 三、AT\&T格式

* 源操作数和目的操作数顺序与Intel格式相反
* (……)：主存地址，可以存在加减法
* %：寄存器前缀
* $：立即数前缀
* 读写长度
  * MOVB $5, (af996h)：MOV byte ptr \[af996h], 5
  * MOVW $5, (af996h)：MOV word ptr \[af996h], 5
  * MOVL $5, (af996h)：MOV dword ptr \[af996h], 5
* MOV 8(%EDX, %EAX, 2)：MOV \[EDX+EAX\*2+8]
  * 偏移量为8
  * 基址寄存器EDX
  * 变址寄存器EAX
  * 比例因子2

## 4.4.2 常用指令

### 一、算术运算

```
ADD d,s		#(d)+(s)→(d)
SUB d,s 	#(d)-(s)→(d)

MUL d,s 	#无符号数乘法
IMUL d,s	#有符号数乘法

DIV s		#无符号数除法，被除数隐式存放在EDX:EAX中(位扩展到64位)
IDIV s		#有符号数除法，(接上)商存入EAX，余数存入EDX

NEG d		#取负数

INC d		#自增++
DEC d		#自减--
```

### 二、逻辑运算指令

```
AND d,s		#与
OR d,s		#或
NOT d		#非
XOR d,s		#异或

SHL d,s		#左移
SHR d,s		#右移
```

### 三、控制流指令

```
JUMP <addr>		#无条件转移指令
CMP a,b			#比较a和b两个数

#在比较之后，可以使用以下指令
JE <addr>		#a==b 则跳转
JE <addr>		#a!=b 则跳转
JE <addr>		#a>b 则跳转
JE <addr>		#a>=b 则跳转
JE <addr>		#a<b 则跳转
JE <addr>		#a<=b 则跳转

LOOP <tag>		##自动ecx--,ecx!=0,则跳转到tag
```

## 4.4.3 具体实现

### 一、条件跳转

源代码

```java
int a = 7;
int b=6;

if (a>b){
    c=a;
} else {
    c=b;
}
```

利用转移指令实现：

```
mov eax,7
mov abx,6
cmp eax,ebx
jg NEXT
mov ecx,ebx
jmp END
NEXT:
mov ecx,eax
END:
```

### 二、循环语句

源代码

```java
int result = 0;
for (int i=1; i<=100; i++){
    result+=1;
}
```

使用转移指令实现

```
#循环初始化
mov eax,0
mov edx,1
#检测是否直接跳出循环
cmp edx,100
jg L2
#循环主体
L1:
add eax,edx
inc edx
#是否继续循环
cmp edx,100
jle L1
#跳出循环
L2:
```

使用loop指令实现

```
mov eax,0
mov edx,1
mov ecx,100		#循环100次
Looptop:
add eax,edx
inc edx
loop Looptop
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aye10032.gitbook.io/computerorganizationnote/di-si-zhang-zhi-ling-xi-tong/4.4-cheng-xu-de-ji-qi-ji-dai-ma.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
