您的当前位置:首页正文

汇编(四)

来源:花图问答

一. DS和[address]

  • CPU要读写一个内存单元时,必须要给出这个内存单元的地址,在8086中,内存地址有段地址和偏移地址

  • 8086中有一个DS寄存器,通常用来存放要访问的数据的段地址。

    mov bx, 1000H
    mov ds, bx
    mov al, [0]
    
    • 3条指令的作用是将10000H(1000:0)中的内存数据赋值到al寄存器中
    • mov al, [address] 的意思将DS:address中的内存数据赋值到al寄存器中
    • 由于al8位寄存器,所以是将一个字节的数据赋值给al寄存器

-8086不支持将数据直接送入段寄存器中,mov ds, 1000H是错误的。

练习 :

写指令,将al中的数据送入内存单元1000H

mov bx, 1000H
mov ds, bx
mov [0], al

二.字符数据的传递(2个字节)

写出下面指令执行后寄存器ax,bx,cx中的值:

内存.png
mov ax, 1000H
mov ds, ax
mov ax, [0]
mov bx, [2]
mov cx, [1]
add bx, [1]
add cx, [2]

结果:

执行结果.png

三.大小端

  • 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中(高低\低高) (Big Endian
  • 小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中(高高\低低) (Little Endian

举个🌰 :

image.png

注意:ARM既可以工作在大端模式,也可以工作在小端模式

练习:

写出下面指令执行后寄存器ax,bx,cx中的值:

image.png
mov ax, 1000H
mov ds, ax
mov ax, 11316
mov [0], ax
mov bx, [0]
sub bx, [2]
mov [2], bx
结果解析.png

四.mov指令

mov 寄存器, 数据          -> 比如: mov ax, 8
mov 寄存器, 寄存器        -> 比如: mov ax, bx
mov 寄存器, 内存单元       -> 比如: mov ax, [0]
mov 内存单元, 寄存器       -> 比如: mov [0], ax
mov 段寄存器, 寄存器       -> 比如: mov ds, ax

注意: "mov 内存单元,内存单元"是不允许的,比如mov[0], [1]

五.add 和 sub指令

addsub指令通mov一样,都有两个操作对象,有如下几种形式:

add 寄存器, 数据  -> add ax, 8
add 寄存器, 寄存器 -> add ax, bx
add 寄存器, 内存单元 -> add ax, [0]
add 内存单元, 寄存器 -> add [0], ax
sub 寄存器, 数据 -> sub ax, 9
sub 寄存器, 寄存器 -> sub ax, bx
sub 寄存器, 内存单元 -> sub ax, [0]
sub 内存单元, 寄存器 -> sub [0], ax

六. 数据段

  • 对于8086来说,在编程是,可以根据需要,将一组内存单元定义为一个段

  • 我们可以将一组长度为N(N <= 64KB)、地址连续、起始地址为16倍数的内存单元当做专门存储数据的内存空间,成为数据段。比如用123B0H~123B9H这段内存空间来存放数据,我们就可以认为123B0H ~ 123B9H是一个数据段,它的段地址为123BH,长度为10个字节。

  • 如何访问数据段中的数据:

    • DS存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元。

练习

各寄存器的初始值:CS = 2000H,IP = 0, DS = 1000H,AX = 0, BX = 0;

  1. 写出CPU执行的指令序列(用汇编指令写出)
  1. 写出CPU执行完指令后,CS,IP和相关寄存器中的数值

3.再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些又是程序?

内存图.png

解析:

  • 因为CS = 2000H, IP = 0, 所以指令寄存器指向地址:20000H,所以首先执行mov ax, 6622H

  • 接着执行:jmp 0ff0: 0100,这里执行跳转指令跳转到地址10000H

  • 在地址10000H处执行mov ax, 2000H,接着执行mov ds, ax这时候ds 的值为2000H

  • 再接着执行mov ax, [0008],这时候将20008H处的数据赋值给ax,所以ax的值为c389H

  • 最后执行mov ax, [0002],这时候将20002处的数据赋值给ax,所以ax的值为EA66.

答案:
CPU指令序列:

mov ax, 6622H
jmp 0ff0:0100
mov ax, 2000H
mov ds, ax
mov ax, [0008]
mov ax, [0002]

执行完指令后:

CS:1000H
IP: 000BH
AX: EA66 
BX : 0
DS: 2000H

内存中: 数据和程序没有任何区别,CS:IP指向的是指令,DS:指向的是数据.