8086汇编

8086入门学习

8086汇编代码

使用debug

image-20230719181638022

  1. 在终端中输入debug进入到调式界面

  2. 查看寄存器输入R

    • r+寄存器变量名直接修改寄存器的值
  3. 查看内存输入D

    image-20230719182834156

    • 也可以添加地址,从1000段地址偏移0开始输出

      image-20230719182309364

  4. 改变内存的内容E

    • 第一种方法

      image-20230719182659159

    • 第二种方法

      image-20230719183431008

  5. 使用A添加汇编代码

  6. T执行插入的指令

  7. U翻译机器码

部分寄存器

image-20230722085403982

指令的学习

mov

image-20230720151104219

  1. 注意逗号后面的控制

  2. 下面操作寄存器的高位和低位

    image-20230720151249768

    注意第三条指令(不包括错误的指令)

    1
    mov ch, 10

    这段代码表示将10给c寄存器的高位(hight)

    由此可以知道直接使用mov直接赋值给低地址位

add

image-20230720152313629

  1. 将两个数相加

  2. 同时也可以实现自己加自己

    image-20230720152634451

  3. 相加如果越位了就直接舍去

  4. 如使用地位相加过后溢位了

    image-20230720153048935

    同样的不会进位

    但是使用的是整个的寄存器那么就会进位

    image-20230720153203861

sub

  1. sub会向下越界

    image-20230722083756095

  2. 同样的如果是操作低位或高位,只会在低位或者高位进行sub计算

mul

image-20230722085536634

image-20230722085647601

  1. 首先应该知道

    乘数一个是放ax或者al当中的,另一个是自己指定的

  2. 存放的时候默认放在ax,如果是16位的乘法,高位就放在dx

div

image-20230722090833052

  1. 除数相当于是我们指定的

    被除数要分情况,被除数是16位放在ax当中;是32就放在dxax当中,高位放在dx地位放在ax

  2. 结果的从存放。

    高位放余数,低位放置商

and

image-20230722091746751

  1. 0就是0

  2. 下面演示操作方法

    image-20230722092236392

    image-20230722092457283

or

  1. 1就是1
  2. 但是在debug界面我们不能使用二进制,所以先要转换成16进制才能计算二进制

左右移的指令

  1. 移动都是移动的是二进制

shl左移

  1. 和C语言的一致,向左移动,然后右边补0

    image-20230722093511339

rol循环左移

  1. 将高位舍去的位数补充到低位

shr右移

ror循环右移

inc自增操作

dec自减操作

nop空的代码段

  1. 大小为一个字节
  2. 可以用存放代码段

xchg交换

  1. 可以用于交换两个数,寄存器或者地址

neg取反

  1. 用于将二进制取反操作

abs带进位的加法

  1. 利用的是cf寄存器

abb带借位的一个减法

  1. 使用的也是cf寄存器

cmp是比较,也是减法

image-20230722170544073

通过相减看是否是相等的

image-20230722171803628

image-20230722172100724

image-20230722172133543

callret

  1. 通过修改cx的值进行跳转

  2. call相当于函数的调用

  3. ret用于函数的结束

  4. 但是整体的结束是INT 21H

  5. CALL 和 RET的都是修改IP的值,也就是说是近转移

  6. CALLF和RETF就是说是远转移,如果通过修改IP不能达到要求,则会修改 CX

  7. 本质都是压栈和弹栈的过程

    CALL是压栈,将代码的地址压栈

    RET是出栈,将代码的地址

offset读取一个函数的地址,然后赋值

image-20230723123016835

  1. 获取一个函数的地址,然后进行操作

lea

  1. 计算有效地址:lea 可以计算一个内存操作数的有效地址,并将结果(即内存地址)加载到目标寄存器中。例如,lea eax, [ebx+ecx*4] 将计算 [ebx+ecx*4] 的有效地址,并将结果存储到寄存器 eax 中。
  2. 进行简单的加法运算:lea 可以执行简单的加法运算,并将结果加载到目标寄存器中。例如,lea eax, [ebx+123]ebx+123 的结果计算出来,并将结果存储到寄存器 eax 中。

终断

  1. 程序停止就是中断

寄存器

段地址和偏移地址

image-20230722100913434

  1. 一个物理地址可以有很多个段地址加偏移地址的组合

    image-20230722101449853

  2. 下面演示使用DS(数据段地址)+偏移地址给ax赋值

    image-20230722102553160

    注意标红的地方就是使用的偏移地址

  3. 不通过r修改DS寄存器

    由于DOS的限制,不能直接使用MOV修改DS寄存器

    但是可以使用下面的例子对DS赋值

    image-20230722103018201

    我们先将值赋给AX然后在对其赋值

CS和IP 代码段寄存器

代码运行地址

image-20230722104944573

  1. 物理的内存等于

    ​ CS*16+IP=内存

  2. 下面使用实例

    • 先将规定地址,在添加汇编代码

      image-20230722105649871

    • 使用U将机器码翻译成汇编代码

      image-20230722105723077

  3. 注意

    如果要指定一段地址运行,需要修改CS和IP的数值

    image-20230722114949873

jump指令

  1. 用于不同内存的跳转

    下面的实现在1E2B:0100运行mov ax,8989

    然后使用jump与运行jump1000:0000

    运行move bx,1212

    image-20230722125003980

    注意在编写的时候我们需要手动跳转内存进行写代码

  1. 先进后出,后进先出

  2. 压栈

    将ax,bx,cx压入栈

    image-20230722130358149

  3. 出栈

    image-20230722130541365

  4. 寻址的实现

    image-20230722131010719

    我们通过记录段地址用SS,使用SP记录偏移的地址

  5. 栈的越界

    image-20230722131701530

    也就是说,计算机不会检测,需要人为的注意栈区的大小

寻址方式

  1. 使用偏移地址的方式
    • 首先使用CS进行段地址的赋值
    • 然后使用偏移地址的方式查找
    • 注意BX寄存器也是可以用来当作偏移地址

SIDI

image-20230722155845770

image-20230722160118625

BX 寄存器BX的替代品

  1. 代表了以SS:BP
  2. 可以用于寻址
  3. 同时还可以使用.表示偏移地址

image-20230722161253506

image-20230722161405353

ES附加段寄存器

相当于备胎,和其他的差不多

image-20230722161635034

标志寄存器

比较器,相当于c++的if

代码段

image-20230722172758881
  1. 注意我们需要先将cs指定,也就是code segment

    还需要将codesg ends 结尾

语法

循环

  1. 使用loop进行循环
  2. 根据CX的值是否为0,进行判断是否是可行的

8086汇编
https://tsy244.github.io/2023/07/15/汇编/8086汇编/
Author
August Rosenberg
Posted on
July 15, 2023
Licensed under