汇编语言

汇编语言

汇编指令 =》通过编译器 =》010100101
伪指令 =》告诉翻译软件也就是编译器,这里怎么翻译,那里怎么翻译,有编译器执行,没有对应的机器指令
符号体系 =》没有对应的机器指令,由编译器执行

机器指令和汇编指令的关系?
通过编译器可以一一对应

CPU 通过指令来控制整个计算机
指令和数据
CPU 在工作时 需要对 指令和数据进行区分

指令和数据是以什么形式存放在内存中的?
以二进制形式存放在内存中的

内存也叫存储单元
最小的存储单位是字节
1字节(Byte) = 2个16进制数字 = 8个2进制数字
1Byte = 8bit
对字节(存储单元)进行编号

CPU对于内存的读写是通过导线和内存进行传输数据,这些导线和平常电子元件常见
铜线一样只是做的细罢了,这些导线在一起通常成为总线,为了区分这些总线传输的
容逻辑上分为3类,地址总线(传输的是内存地址)、控制总线(传输的是控制命令
)、数据总线(传输的是控制的数据)

ROM 只允许读取,不允许写入,不通电的情况下里面的数据还是保持的
RAM 运行写入,允许读取,电没了就没了

通用寄存器 一般存放数据
通用寄存器表示形式 = AX-4E20
AX = AH + AL    H = high 高(前两位)  L = low 低(后两位)
BX = BH + BL
CX = CH + CL
DX = DH + DL

寄存器是相互独立的
AH 和 AL 是没有关系的

move ax,bl
这一行代码是错的,8位寄存器不能写到16位的寄存器中
注意寄存器能够写的最大值  一个字节是 255 = FF
AX = 65535 = FFFFH

表示地址信息的寄存器
左边:段地址  右边:偏移地址

虚拟 8086CPU  20根地址线  20bit   寄存器16位,只有16bit
位数不匹配,属于设计失误
补救:
物理地址 = 基础地址 + 偏移地址
基础地址 = 段地址 = 16(10H)

段地址   偏移地址
1238H   C8H     =   1230H * 10H + C8H
= 12300H + C8H = 123C8H

帮助理解的小例子
学校    体育馆   图书馆   16进制
0       2000    2826
我现在有2张能写4位数字的字条
第一张     第二张
0      +   2826
2000   +   826

我现在有2张能写3位数字的纸条
第一张     第二张
200    +   826      =    200(段地址)*10  +  826(偏移地址) = 2826

1.CPU中存放段地址信息的寄存器?  ds es ss cs
2.CPU中存放偏移地址信息的寄存器? bp ip sp si di bx(bx可以把地址信息当做数据来存储)
3.偏移地址能够表示的最大值是多少? FFFFH


CPU是怎么区分指令和数据的?

CPU将CS:IP所组合(指向)出来的地址里面的内容全部当做指令
指令和数据存放内存中没有区别!!

指令是有长度的,可以由多个字节组成

指令执行的过程
1. CPU 从 cs:ip 所组合的地址中读取指令,将这个指令存放到指令缓冲器中
2. IP = IP + 所读指令的字节数
3. 执行指令缓存器中的内容,回到步骤1 重复这个过程

转移指令
能够修改ip或者cs 或者同时修改的指令
jmp 2000:0   前面的是ip,后面的是cs
jmp 寄存器    例:jmp ax  就等于把ax的地址赋值给ip

检测点
1.下面的3条指令执行后,CPU 几次修改了IP?都是在什么时候?最后IP中的值是多少?
move ax,bx => 指令缓存器 => 1 => 执行
sub ax,bx  => 指令缓存器 => 1 => 执行
jmp ax     => 指令缓存器 => 1 => 执行 => 1

答案:一共执行了4次,最后 ip = 0

call 转移指令,相当于调用方法
    call cpy_Boot   : --->指令缓冲器中--->ip--->
                                         :call
    move ax,1000H   :IP指向move ax,1000H    将ip保存起来-->跳转到cpy_Boot方法里
    move ax,4c00H
int 21H
:---------------
cpy_Boot:
    move bx,1000H
    move bx,1001H
    ret             :返回,跳转回call方法保存的ip地址所指向的指令
    move cx,2000H   该指令并不会被执行

汇编程序员就是通过汇编指令修改 CPU 的寄存器中的内容控制 CPU,从而达到控制整个计算机的目的

add指令加法练习
1.写几条指令,将一段内存中连续3个字型数据累加存放到 AX 中
20000H 12H  => 3412H
20001H 34H
20002H 99H  => 8899H
20003H 88H
20004H FFH  => EEFFH
20005H EEH
指令代码如下:
    move bx,2000H
    move ds,bx
    move ax,0
    add ax,ds:[0]
    add ax,ds:[2]
    add ax,ds:[4]

段地址:偏移地址
ss:sp

push ax  =>  sp-2  =>  ax存放到ss:sp-2
pop ax  =>  ss:sp存放到ax  =>  sp+2

1. CS:IP 和指令有关
2. DS:[0] [1] ...  和数据有关
3. SS:SP   临时性数据

数据在哪里
数据的长度   字节型数据  字型数据 AX BX CX DX AH AL BH BL
数据的处理   ADD SUB
数据存放到哪里

数据是我们自己安排的
存放到哪里也是自己安排
指令在哪里也要自己安排

自由的代价:谨慎

汇编语言
汇编指令
伪指令     由编译器执行的
符号体系

1.编写源代码 源程序
2.编译(通过编译器)
3.链接
4.执行程序

loop 循环指令   CX = CX - 1  检测CX是不是等于0
循环体
CX  循环次数

loop循环的执行顺序是先执行代码,然后将CX减去1,拿CX减去1的结果与0进行比较,如果不相等则跳转到上方进行循环,如果等于0则继续执行下方的代码。

能够改变 CS:IP 的是转移指令
loop是转移指令

    move ax,0
    move cx,123
addNumber:  add ax,236
            move dx,1000H
            move dx,2000H
            loop addNumber   // 标号 地址

            move ax,4C00H
            int 21H

coder ends
end


and指令 和 or指令
and指令:逻辑运算指令,按位进行 与 运算
or指令:逻辑运算指令,按位进行 或 运算

ds:[bx+5]   偏移地址的组合

inc(a) 就相当与 a:=a+1 即在本次循环是累加

si和di 偏移地址寄存器
使用方法和bx一样
ds:[bx]
ds:[bx+5]

start:  move ax,data
        move ds,ax
        move es,ax

        move si,0
        move di,16 //数据从哪里来 ds:[si]   数据到哪里去 es:[di]

        move cx,8

copyData:   move dx,ds:[si]
            move es:[di],dx
            add si,2
            add di,2
            loop copyData
/* 第二种解决办法
start:  move ax,stack
        move ss,ax
        move sp,32
 
         move ax,data
         move ds,ax
         move es,ax
         
         move si,0
         move di,16 //数据从哪里来 ds:[si]   数据到哪里去 es:[di]
 
 move cx,8
copyData:   push ds:[si]
            pop es:[di]
            add si,2
            add di,2
            loop copyData
 */

内存访问形式
ds:[bx+si]
ds:[bx+di]
ds:[bx+si+4]
ds:[bx+di+5]

ds:[?]  ds为段地址 []里面的值为偏移地址

一个字型数据占两个字节 一个字节8位

归纳1:数据可以存放在哪?
1.CPU的寄存器中
ax,bx,cx,dx  ah,al  bh,bl  ch,cl  dh,dl
2.内存中
地址信息 8086CPU
段地址信息:偏移地址信息
ds          ip
es          sp
ss          si
cs          di
            bp
ds:[0]  ds:[bx]  ds:[si]  ds:[di]  ds:[bp]
//ds:[si+di] si+di是不允许这么写的
ds:[bx+si+2]  ds:[bx+di]  ds:[bx+si]
ss:[bp+si+2]
3.端口中
归纳2:数据的长度
字型数据                 字节型数据
mov ax,1                move al,1
move bx,ds:[0]          move al,bl
move ax,ds
move ax,1000
move ds,ax
inc ax

把数据当做字型数据存放到ds中         把数据当做字型数据存放到ds中
mov word ptr ds:[0],1           mov byte ptr ds:[0],222
inc word ptr ds:[bx]            inc byte ptr ds:[0]

除数    8bit    16bit  存在内存单元中 或者 寄存器中
被除数  AX或者   AX和BX中
如果除数为8bit,被除数则为16bit,存放在AX中
如果除数为16bit,被除数则为32bit,AX存放低16bit,DX存放高16bit
结果:如果除数为8bit,则AL 存放 商,AH 存放余数
     如果除数为16bit,则AX 存放 商,DX 存放余数


db 占1个字节
dw 占2个字节
dd 占4个字节

inc bx 将bx中的值加1
dec bx 将bx中的值减去1

转移指令
灵活性
标号处的地址 - jmp指令后的第一个字节的地址 = 位移    ;编译器
jmp     段间转移
        短转移     -128 ~ 127
DFFFSET  伪指令

条件转移指令
jcxz    标号     j = jmp    cx 寄存器    z = zero
if cx 等于 0  jmp 标号

nop 指令  ;CPU 什么事都不做  只是占用两个字节

ret    pop ip     ss:sp 字型数据 => ip     sp+2
retf   pop ip  pop cs

jmp  位移
call 指令比jmp多做了一件事   push ip   push的是第2步时已经 自加所读指令字节数 的ip

call s  与 ret 配合使用  call:push ip  ret:pop ip
call far ptr s 与 retf 配合使用
call far ptr:push cs, push ip  retf:pop ip pop cs

mul 乘法
8bit   一个字节   al   bl    mul byte ptr ds:[0]     AX
16bit  2个字节    ax   bx    mul word ptr ds:[0]    AX      DX


标志位寄存器
15 14 13 12 11 10 9  8  7  6  5  4  3  2   1   0
            OF DF IF TF SF ZF    AF    PF      CF
运算溢出,溢出的1是存在 CF 中

CF: Carry Flag
ZF: Zero Flag
PF: Parity Flag
SF: Sign Flag

标志      真值为1        假值为0
OF         OV           NV  Overflow    not Overflow
SF         NG           PL  NG = negative 负数  PL = positive 正数
ZF         ZR           NZ  ZR = Zero   NZ = not Zero
PF         PE           PO  PE = Even 偶数    PO = odd 奇数
CF         CY           NC  CY = Carry Yes(进位)   NC= notCarry
DF         DN           UP  DN = Down

mul、div 乘法、除法指令不影响标志位
CF 是把结果都当做无符号运算
OF 是有符号运算

adc指令   add carry
add ax,bx   ax = ax + bx + carry

sbb     sub carry

cmp指令
sub ax,bx  ax = ax - bx
cmp ax,bx   只执行 ax-bx 这个过程,不保存结果至ax中,但是会修改标志位

je  equal
jne not equal
jb  below
jnb not below
ja  above
jna not above


内中断
中断:发生了需要CPU立刻去处理的信息
1.除法错误 divide overflow
2.单步执行  debug
3.执行into指令
4.执行int指令

中断信息  需要一个程序去处理
CS,IP => 需要处理的程序入口 段地址,偏移地址

中断向量表               中断类型码
0号处理中断信息的程序地址   CS:IP
1号处理中断信息的程序地址   CS:IP
2号处理中断信息的程序地址   CS:IP
0000:0000 - 0000:03FF

段地址:N*4+2   偏移地址:N*4

中断过程
1.取得中断类型码
2.保存标志寄存器 => 栈  pushf
3.将标志寄存器的第8 TF 和 第9位 IF 设置为0
4.push cs
5.push ip
6.cs = N*4+2  ip = N*4

中断处理程序返回的办法
//ss:sp  ip cs pushf
iret    // 一条程序等于下面三条程序的效果
pop ip
pop cs
popf

int 指令
1.取中断类型码N
2.标志位寄存器入栈 IF = 0   TF = 0
3.push cs    push ip
4.cs = N*4+2   ip = N*4

BIOS 和 DOS 所提供的中断的例程 = 中断程序
BIOS 系统登记在中断向量表里的
ROM内存只允许读取 不允许写入的  固化在内存中
BIOS Basic Input output System

1.硬件系统的检测和初始化程序
2.将外部中断和内部中断程序登记在 中断向量表中
3.用于对硬件设备进行 I/O 操作的中断程序 放到中断向量表中
4.其他相关于硬件系统的 中断程序

电脑开机
CS = FFFF   IP = 0
1.硬件系统的检测和初始化程序
2.将中断程序的 CS 和 IP 直接登记在中断向量表中
3.调用 into9H 进行操作的系统引导,将计算机交给操作系统控制 DOS
4.DOS 系统将相应的 中断程序入口地址 存到中断向量表中 包括程序

shl 左移指令
1.将一个寄存器 或者内存单元 中的数据向左移位 bit位
2.将移除的这一位 放到 CF 中
3.最低位用 0 补充

shr 右移指令

用int 13H 中断程序,对磁盘进行读写  ;BIOS

软盘  C盘 0面0道1扇   ;start system
上下两面
一面 = 80磁道
-磁道 = 18扇区
-扇区 = 512字节

2 * 80 * 18 * 512 = 1440KB     1.44M

面号 从0开始
磁道 从0开始
扇区 从1开始

你可能感兴趣的:(汇编语言)