汇编入门log(三)
学习汇编的第三天,记录学习汇编的最后一部分。
逻辑指令
逻辑指令有
- AND-与
- OR-或
- XOR-异或
- TEST-配合跳转,工作原理与AND相同,但不改变操作数
- NOT-取反
条件
条件本质上就是利用跳转,实现走入不同的分支
可以分为
- 无条件跳转
- 条件跳转
无条件跳转
由JMP指令执行。JMP指令提供一个标签名称,其中控制流立即转移,语法为:
1 | JMP label |
示例:
1 | MOV AX, 00 ; Initializing AX to 0 |
条件跳转
条件跳转需要使用CMP指令与J?指令共同完成。
CMP指令
比较两个操作数,不会干扰目标或源操作数,与条件跳转指令一起用于决策,语法为:
1 | CMP destination, source |
示例:
1 | CMP DX, 00 ; Compare the DX value with zero |
条件跳转指令
其实我还不熟悉,用的时候再熟悉吧。
用于算术运算的有符号数据上使用的条件跳转指令
| 说明 | 描述 | 已测试标志 |
|---|---|---|
| JE/JZ | Jump Equal or Jump Zero | ZF |
| JNE/JNZ | Jump not Equal or Jump Not Zero | ZF |
| JG/JNLE | Jump Greater or Jump Not Less/Equal | OF, SF, ZF |
| JGE/JNL | Jump Greater/Equal or Jump Not Less | OF, SF |
| JL/JNGE | Jump Less or Jump Not Greater/Equal | OF, SF |
| JLE/JNG | Jump Less/Equal or Jump Not Greater | OF, SF, ZF |
用于逻辑运算的无符号数据的条件跳转指令
| 说明 | 描述 | 已测试标志 |
|---|---|---|
| JE/JZ | Jump Equal or Jump Zero | ZF |
| JNE/JNZ | Jump not Equal or Jump Not Zero | ZF |
| JA/JNBE | Jump Above or Jump Not Below/Equal | CF, ZF |
| JAE/JNB | Jump Above/Equal or Jump Not Below | CF |
| JB/JNAE | Jump Below or Jump Not Above/Equal | CF |
| JBE/JNA | Jump Below/Equal or Jump Not Above | AF, CF |
条件跳转指令有特殊用途并检查标志的值
| 说明 | 描述 | 已测试标志 |
|---|---|---|
| JXCZ | Jump if CX is Zero | none |
| JC | Jump If Carry | CF |
| JNC | Jump If No Carry | CF |
| JO | Jump If Overflow | OF |
| JNO | Jump If No Overflow | OF |
| JP/JPE | Jump Parity or Jump Parity Even | PF |
| JNP/JPO | Jump No Parity or Jump Parity Odd | PF |
| JS | Jump Sign (negative value) | SF |
| JNS | Jump No Sign (positive value) | SF |
循环
语法
1 | LOOP label |
其中,label是目标标签,用于识别跳转指令中的目标指令。
LOOP指令假定ECX寄存器包含循环计数,知道ECX寄存器值归零。
示例:
1 | section .text |
数字
没什么内容,就是介绍汇编语言中,可以使用ASCII与BCD表示数字。
字符串
指定字符串长度的方法:
- 显示存储字符串长度
- 使用哨兵字符
可以使用$位置计数器符号来显示存储字符串长度
1 | msg db 'Hello, world!',0xa ;our dear string |
或者
也可以存储带尾随哨兵字符的字符串来分割字符串
1 | message DB 'I am loving it!', 0 |
数组
与C语言类似,只是初始化方式,例如:
1 | INVENTORY DW 0 |
过程
感觉类似实现函数与调用
定义过程的语法为
1 | proc_name: |
使用CALL指令从另一个函数调用该过程,语法为
1 | CALL proc_name |
被调用过程使用 RET 指令将控制权返回给调用过程。
堆栈数据结构
提供两种堆栈操作指令,其语法如下
1 | PUSH operand |
递归
递归有两种:直接递归和间接递归。
直接递归,自己调用自己
间接回归,一个过程调用另一个过程,另一个过程调用前一个过程
宏
编写宏是确保汇编语言模块化编程的另一种方法。
- 宏是一系列指令,由名称指定,可以在程序中的任何位置使用。
- 在 NASM 中,宏是使用 %macro 和 %endmacro 指令定义的。
- 宏以 %macro 指令开始,以 %endmacro 指令结束。
宏定义的语法
1 | %macro macro_name number_of_params |
示例:
1 | ; A macro with two parameters |
文件管理
由于暂时并不操作文件,故本部分略过。
内存管理
sys_brk() 系统调用由内核提供,用于分配内存而无需稍后移动它。 此调用在内存中的应用程序映像后面分配内存。 该系统函数允许您设置数据部分中的最高可用地址。
该系统调用有一个参数,即需要设置的最高内存地址。 该值存储在 EBX 寄存器中。
如果出现任何错误,sys_brk() 返回 -1 或返回负错误代码本身。 以下示例演示了动态内存分配。
1 | section .text |
