8086 学习记录笔记

寄存器:

常用:

  1. AX寄存器:是8086中最重要的寄存器之一,它是一个16位寄存器,可以用来存储一般的数据和算术运算的结果。

  2. BX寄存器:也是一个16位寄存器,常用于存储地址和指针。

  3. CX寄存器:也是一个16位寄存器,常用于计数和循环操作,例如循环计数器。

  4. DX寄存器:也是一个16位寄存器,常用于I/O操作和乘法/除法运算。

  5. SI寄存器:也是一个16位寄存器,常用于源数据的指针。

  6. DI寄存器:也是一个16位寄存器,常用于目标数据的指针。

  7. BP寄存器:也是一个16位寄存器,通常用于指向堆栈中当前帧的基地址。

  8. SP寄存器:也是一个16位寄存器,通常用于指向堆栈顶部的指针。

  9. CS寄存器:指向代码段的起始地址。代码段包含程序的指令代码,CS的值加上IP寄存器的值,就可以确定下一条要执行的指令的地址。

  10. DS寄存器:指向数据段的起始地址。数据段包含程序中使用的各种数据。

  11. ES寄存器:附加段寄存器,指向附加数据段的起始地址。它常常用于存储一些数据结构或者其他需要附加的数据段。

  12. SS寄存器:指向堆栈段的起始地址。堆栈段用于存储程序的过程调用和返回地址以及其他重要的信息。

 FLAGS寄存器:

        

  1. CF(Carry Flag)进位标志位:用于标识上一次操作是否发生了进位或借位。

  2. PF(Parity Flag)奇偶标志位:用于标识结果中1的个数是否为偶数。

  3. AF(Auxiliary Carry Flag)辅助进位标志位:用于标识上一次操作是否在低四位(Nibble)上发生了进位或借位。

  4. ZF(Zero Flag)零标志位:用于标识结果是否为零。

  5. SF(Sign Flag)符号标志位:用于标识结果是否为负数。

  6. TF(Trap Flag)陷阱标志位:用于调试程序,设置后,程序将进入单步调试模式,一条指令执行一次。

  7. IF(Interrupt Flag)中断标志位:用于控制是否响应可屏蔽中断。

  8. DF(Direction Flag)方向标志位:用于控制字符串操作方向(正向或反向)。

  9. OF(Overflow Flag)溢出标志位:用于标识上一次操作是否发生了溢出。

声明变量:

DB(Define Byte)指令:用于声明一个字节变量                                                        

语法为:<name> DB <value>。 其中,<name>是变量名称,<value>是字节值,可以是一个十进制或十六进制数,也可以是一个字符。

例如,声明一个名为myByte的字节变量,值为10,可以使用以下语句:

                                        myByte DB 10

DW(Define Word)指令:用于声明一个字变量

语法为:<name> DW <value>。其中,<name>是变量名称,<value>是字值,可以是一个十进制或十六进制数。

例如,声明一个名为myWord的字变量,值为65535,可以使用以下语句:

                                        myWord DW 65535

DD(Define Double word)指令:用于声明一个双字变量,语法为:<name> DD <value>。其中,<name>是变量名称,<value>是双字值,可以是一个十进制或十六进制数。

例如,声明一个名为myDword的双字变量,值为4294967295,可以使用以下语句

                                        myDword DD 4294967295

DUP 是一个用于重复复制指定数据的伪指令(pseudo-instruction)。dup指令后面跟着一个数字或一个表达式,表示要创建的元素数量,紧接着是一个数据项,表示要重复的数据内容。指令将在程序中为该数组分配足够的空间,并将指定的数据复制到每个元素中。

下面是一些常见的dup指令用法:

  • 使用dup指令声明一个由多个字节组成的数组,例如: myArray db 10 dup(0)

这将声明一个名为myArray的数组,包含10个字节,每个字节的值为0。

  • 使用dup指令声明一个由多个字组成的数组,例如:myArray dw 5 dup(1234h)

这将声明一个名为myArray的数组,包含5个字,每个字的值为0x1234。

  • 使用dup指令声明一个由多个双字组成的数组,例如:myArray dd 20 dup(0)

这将声明一个名为myArray的数组,包含20个双字,每个双字的值为0。

运算符:

  •  算术运算符

- `+`:加法运算符,用于将两个数相加。
- `-`:减法运算符,用于将两个数相减。
- `*`:乘法运算符,用于将两个数相乘。
- `/`:除法运算符,用于将一个数除以另一个数。

  • 逻辑运算符

- `AND`:逻辑与运算符,用于对两个数执行按位与操作。
- `OR`:逻辑或运算符,用于对两个数执行按位或操作。
- `XOR`:逻辑异或运算符,用于对两个数执行按位异或操作。
- `NOT`:逻辑非运算符,用于对一个数执行按位取反操作。

  • 移位运算符

- `SHL`:左移运算符,用于将一个数向左移动指定的位数。
- `SHR`:右移运算符,用于将一个数向右移动指定的位数。

  • 比较运算符

- `CMP`:比较运算符,用于比较两个数的大小,结果将设置FLAGS寄存器的状态。

  • 其他运算符

- `MOD`:取模运算符,用于计算一个数除以另一个数的余数。
- `ADDR`:地址运算符,用于获取变量的内存地址。

需要注意的是,在使用运算符时,需要根据操作数的数据类型和长度来选择正确的运算符,以确保程序能够正确地执行所需的运算。此外,在进行算术和逻辑运算时,也需要注意溢出和标志位的状态,以便正确处理可能出现的异常情况。

example:

下面是一些使用8086汇编语言中的运算符的示例:

1. 算术运算符
 

MOV AX, 10    ; 将值10存储在AX寄存器中
ADD AX, 20    ; 将值20加到AX中,结果为30
SUB AX, 5     ; 将值5从AX中减去,结果为25
IMUL AX, BX   ; 将AX和BX中的值相乘,结果存储在AX中
IDIV BX       ; 将AX中的值除以BX中的值,商存储在AL中,余数存储在AH中

2. 逻辑运算符

MOV AX, 1101b   ; 将二进制数1101存储在AX中
MOV BX, 1010b   ; 将二进制数1010存储在BX中
AND AX, BX      ; 将AX和BX中的值进行按位与操作,结果存储在AX中
OR AX, BX       ; 将AX和BX中的值进行按位或操作,结果存储在AX中
XOR AX, BX      ; 将AX和BX中的值进行按位异或操作,结果存储在AX中
NOT AX          ; 对AX中的值进行按位取反操作,结果存储在AX中

3. 移位运算符

MOV AX, 1000b    ; 将二进制数1000存储在AX中
SHL AX, 2        ; 将AX中的值向左移动2位,结果为0010 0000b(0x20)
SHR AX, 1        ; 将AX中的值向右移动1位,结果为0001 0000b(0x10)

4. 比较运算符

MOV AX, 10       ; 将值10存储在AX寄存器中
CMP AX, 20       ; 比较AX中的值和20,设置FLAGS寄存器的状态
JE equal         ; 如果AX和20相等,跳转到equal标签处
JG greater       ; 如果AX大于20,跳转到greater标签处
JL less          ; 如果AX小于20,跳转到less标签处

5. 其他运算符

MOV AX, 25       ; 将值25存储在AX寄存器中
MOV BX, 7        ; 将值7存储在BX寄存器中
MOV DX, 0        ; 将值0存储在DX寄存器中
DIV BX           ; 将AX中的值除以BX中的值,商存储在AL中,余数存储在AH中
MOV DX, AX       ; 将DX中的值设为余数
MOV AX, 25       ; 将值25存储在AX寄存器中
ADDR myVar       ; 将变量myVar的内存地址存储在AX中

需要注意的是,这些示例仅用于说明运算符的基本用法,实际的程序

 栈:

        在8086汇编语言中,栈是一个非常重要的概念,它是一种后进先出(LIFO)的数据结构,通常被用来保存函数的局部变量、程序返回地址等。在8086中,栈是由SS(栈段寄存器)和SP(栈指针寄存器)两个寄存器来控制的。

        当程序执行CALL指令时,它会将返回地址压入栈中,然后跳转到函数的代码中执行。当函数执行完毕后,它会使用RET指令返回到调用它的代码中,并从栈中弹出之前压入的返回地址。此外,函数还可以使用PUSH指令将一些数据压入栈中,使用POP指令从栈中弹出数据。

        栈的大小是可以通过改变SS和SP寄存器的值来动态调整的。在执行CALL指令之前,需要将当前栈指针的值保存到SP寄存器中,以便在函数返回时恢复栈的状态。在执行RET指令之前,需要将栈中参数的值弹出,以便恢复栈的状态。

在使用栈时,需要注意以下几点:

  1. 栈的大小是有限制的,如果栈溢出,会导致程序崩溃或出现未定义行为。
  2. 需要注意栈的指针位置,以免发生栈溢出或数据丢失。
  3. 使用栈时,需要注意数据类型的大小,以免造成栈空间的浪费或数据的截断。
  4. 需要遵循栈的后进先出的原则,否则可能会导致程序错误。

        总之,在8086汇编语言中,栈是一种非常重要的数据结构,程序员需要了解它的原理和使用方法,以便正确地使用它来保存数据和返回地址。

 跳转语句:

        在8086汇编语言中,跳转语句可以使程序跳转到指定的代码段中执行,从而实现程序流程的控制。跳转语句可以根据条件进行跳转,也可以无条件跳转。

常见的跳转语句包括:

  • JMP:无条件跳转语句。可以跳转到任何一个指定的代码段中执行,常用于实现程序的无条件跳转。
  • JZ/JNZ:条件跳转语句。当零标志位ZF为1时,执行JZ指令跳转,否则执行JNZ指令跳转。通常用于实现条件分支和循环结构。
  • JE/JNE:条件跳转语句。当相等标志位ZF为1时,执行JE指令跳转,否则执行JNE指令跳转。通常用于实现条件分支和循环结构。
  • JA/JAE/JB/JBE:条件跳转语句。分别表示无符号数的大于、大于等于、小于、小于等于,用于实现无符号数的条件分支和循环结构。
  • JG/JGE/JL/JLE:条件跳转语句。分别表示带符号数的大于、大于等于、小于、小于等于,用于实现带符号数的条件分支和循环结构。
  • LOOP/LOOPE/LOOPNE:循环跳转语句。LOOP指令将CX寄存器的值减1,然后跳转到指定的代码段中执行,如果CX寄存器的值不为零,就继续执行循环体。LOOPE和LOOPNE指令在执行循环体之前会检查ZF标志位的值,以确定是否需要继续执行循环。
  • CALL/RET:子程序调用和返回指令。CALL指令用于跳转到一个子程序中执行,RET指令用于从子程序返回到调用者中执行。

        在使用跳转语句时,需要注意以下几点:

  1. 指定的代码段必须存在,否则会导致程序崩溃或出现未定义行为。
  2. 跳转语句会影响程序流程的控制,需要仔细考虑程序的逻辑结构,以避免出现逻辑错误。
  3. 需要注意跳转语句的条件和目标地址,以确保程序能够正确地跳转到指定的代码段中执行。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值