汇编语言基于8086CUP(想学操作系统的前奏!!!)

1、汇编语言的产生

1.1、思维图

1.2、单位转换

1B=8bit

1KB=1024B

1MB=1024KB

1GB=1024MB

1TB=1024GB

1字=2字节=2B=16位

1.3、储存器与内存

因为在这些总线上传输的都是2进制的数,所以可能传输的是相同的2进制数,需要区分哪些是数据,哪些又是指令,所以需要通过不同的总线就行传输来控制。

地址总线:20位2进制

数据总线:16位2进制

控制总线:16位2进制

2、寄存器和内存、栈

2.1、14个寄存器

AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW;

几位寄存器,表示可以存储几位二进制数

AX,BX,CX,DX一般被称为通用寄存器,

AX可以分为AH和AL

BX可以分为BH和BL

CX可以分为CH和CL

DX可以分为DH和DL

2.2、地址总线

由于8086有20位的地址总线,所有在传输16位时需要地址加法器进行处理变成20位

地址加法器:物理地址=段地址*16+偏移地址

传送地址时需要传送两个16位的地址,一个称为段地址,一个称为偏移地址

段寄存器:CS,DS,SS,ES

CS:为代码段寄存器

IP:指令指针寄存器

2.3、DS和[address]

这样的指令 mov ax,[0] (调试的时候可以这么写,写.asm源文件时需要写成 mov bx,0,mov ax,[bx];需要bx中间量来转换一下) 把默认段地址+偏移地址的第一位取出来放到ax上

DS存放的是默认的段地址

2.4、栈(Last in frist out)后进先出

push(入栈)

pop(出栈)

段寄存器SS:存放栈顶的段地址

寄存器SP:存放栈顶的偏移地址

SS:SP表示栈顶元素

2.5、SI和DI

SI和DI,也用来表示偏移地址,使用[bx]时不够用,所以可以使用[SI],[DI]

2.6、栈解决多层循环问题

2.7、寻址方式

寻址方式 含义 名称 常用格式举例
[idata] EA=idata;SA=(ds) 之间寻址 [idata]
[bx]
[si]
[di]
[bp]
EA=(bx);SA=(ds)
EA=(si);SA=(ds)
EA=(di);SA=(ds)
EA=(bp);SA=(ss)
寄存器间接寻址 [bx]
[bx+idata]
[si+idata]
[di+idata]
[bp+idata]
EA=(bx)+idata;SA=(ds)
EA=(si)+idata;SA=(ds)
EA=(di)+idata;SA=(ds)
EA=(bp)+idata;SA=(ss)
寄存器相对寻址 用于结构体[bx].idata
用于数组,idata[si]<br/
[bx+si]
[bx+di]
[bp+si]
[bp+di]
EA=(bx)+(si);SA=(ds)
EA=(bx)+(di);SA=(ds)
EA=(bp)+(si);SA=(ss)
EA=(bp)+(di);SA=(ss)
基址变址寻址 用于二维数组,[[bx][si]][si]
[bx+si+idata]
[bx+di+idata]
[bp+si+idata]
[bp+di+idata]
EA=(bx)+(si)+idata;SA=(ds)
EA=(bx)+(di)+idata;SA=(ds)
EA=(bp)+(si)+idata;SA=(ss)
EA=(bp)+(di)+idata;SA=(ss)
相对基址变址寻址 用于表格
二维数组

2.8、标志位

标志位 作用
ZF 如果执行的结果为0,ZF=1,反之
PF 如果执行的结果中有偶数个1,则PF=1,反之
SF 如果执行的结果中最高位为1,则SF=1,反之
CF 如果计算出现进位或者借位,加法进位,减法借位,会在CF中标志1
OF 如果无符号计算,出现位不够用,出现溢出,会在OF中标出1
DF DF决定串传送指令后,si和di方向的改变,DF=0,+;DF=1,-
TF RF位为1,就产生单步中断,也就是指令t

无符号数:cmp ax,bx

  1. 如果(ax)=(bx),则(ax)-(bx)=0,所以:ZF=1
  2. 如果(ax)!=(bx),则(ax)-(bx)!=0,所以:ZF=0
  3. 如果(ax)<(bx),则(ax)-(bx)将产生借位,所以:CF=1
  4. 如果(ax)>=(bx),则(ax)-(bx)将不借位,所以:CF=0
  5. 如果(ax)>(bx),则(ax)-(bx)不借位且结果不为0,所以:CF=0,且ZF=0
  6. 如果(ax)<=(bx),则(ax)-(bx)可能借位,可能为0,所以:CF=1或者ZF=1

有符号数:cmp ah,bh

  1. 如果(ah)<(bh),则(ah)-(bh)最高位会为1,如果不溢出,则SF=1,OF=0
  2. 如果(ah)>(bh),则(ah)-(bh)最高位会为1,如果溢出,则SF=1,OF=1
  3. 如果(ah)<(bh),则(ah)-(bh)最高位会为0,如果溢出,则SF=0,OF=1
  4. 如果(ah)>=(bh),则(ah)-(bh)最高位会为0,如果不溢出,则SF=0,OF=0

3、汇编指令

3.1、汇编指令的用法

汇编指令 语法描述
mov ax,18 ax=18
add ax,18 ax=ax+18
sub ax,18 ax=ax-18
inc ax ax=ax+1
dec ax ax=ax-1
jmp 段地址:偏移地址 修改CS和IP的内容(在汇编指令使用,编译器不认识)
push ax 把ax入栈
pop ax 把栈顶元素出栈保存到ax中
loop S:需要循环的指令段 loop S 控制循环的指令,具体循环多少次,由CX中的数决定
dw dw 0123H,1234H,0024H 定义数据存放在内存中,占两个字节
db db 0,1,2,4,5,6,7,8 定义数据存放在内存中,占一个字节
and and al,11011111b 与运算,把al的第五位二进制转化为0
or or al,00100000b 或运算,把al的第五位二进制转化为1
div div bx 除法运算,{(dx)*10000H+(ax)}/(bx)
mul mul bx 乘法运算,(dx)10000H+(ax)=(ax)(bx),都是8位就存放在ax中
dd 定义数据存放在内存中,占四个字节,2个字,32位
dup db 200 dup(0)
db 2 dup('ab','AB')
定义了200个连续为0的字节
定义了"adABabAb"的8个字节的数据
jmp short s 段内转移,指令跳转到标号s处,位移为8位
jmp near ptr s 段内转移,指令跳转到标号s处,位移为16位
jmp far ptr s 段间转移,指令跳转到标号s处,改变CS:IP为s处的CS,IP
jmp ax 指令跳转到ax存放的值当作ip去转移
jmp word ptr 内存地址 段内转移,存放的一个字,表示跳转的偏移地址IP
jmp dword ptr 内存单元地址 段间转移,存放的两个字,表示跳转(CS)=(内存+2),(IP)=(内存)
jcxz s 条件段内转移,如果(cx)=0跳转到s处,否则不跳转
mov ax,offset s 取得s处的偏移地址,把值赋给ax
ret 表示把栈顶的元素值给了IP,改变程序执行的位置
retf 表示把栈顶的元素值给了IP,第二个值给 CS
call s 把当前IP入栈,在跳转(位移16位来实现的)到s处,
call far ptr s 把CS入栈、把IP入栈,把s处的段地址给CS、偏移地址给IP
call ax 把当前IP入栈,把通用寄存器ax的值给IP
call word ptr 内存单元地址 把当前IP入栈,IP该我内单元地址2字节
call dword ptr 内存单元地址 把当前CS入栈、IP入s栈,把高位2字节给CS、低位2字节給IP
abc abc ax,bx 带进位加法指令,(ax)=(ax)+(bx)+CF
sbb sbb ax,bx 带进位减法指令,(ax)=(ax)-(bx)-CF
cmp cmp ax,bx 结果不会保存在任何位置,但会影响标志位的变化
je s 等于则转移到 s标志位,ZF=1,equal:等于
jne s 不等于则转移 s标志位,ZF=0,
jb s 低于转移到 s标志位,CF=1,below:小于
jnb s 不低于转移到 s标志位,CF=0
ja s 高于转移到 s标志,CF=0,ZF=0,above:大于
jna s 不高于则转移到 s标志位,CF=1,或者ZF=1
movsb 将ds:si中的值送入es:si中:((es)16+(di))=((ds)16+(si)}),
如果DF=0,则(si)=(si)+1,(di)=(di)+1;
如果DF=1,(si)=(si)-1,(di)=(di)-1
movsw 以字的单元传送,规则同movsb
rep movsb 根据cx的值来重复传送cx次,实现传送字符串的作用
cld 将标志寄存器DF=0
std 将标志寄存器DF=1
pushf 将标志寄存器的值压栈
popf 弹栈出到标志寄存器中
iret 在中断程序执行,IP,CS,标志寄存器的弹栈
shl 向左移动一位,右边补零,移出的一位保存道CF中
shr 向右移动一位,左边补零,移出的一位保存道CF中
cli 将标志寄存器IF=0,不处理外中断
sti 将标志寄存器IF=1,处理外中断

3.2、Windows11下载Dosbox来使用debug命令窗口

第一步去官网下载:Dosbox;[官网 ][ https://www.dosbox.com/download.php?main=1 ]

第二步修改你需要在哪个盘哪个文件中操作:

masm文件

asm文件

最后打开DOSbox.exe就可以操作了

Debug指令

R命令,查看、改变CPU寄存器的内容

D命令,查看内存中的内容

E命令,改变内存中的内容

A命令,可以在段地址CS,偏移地址IP写入一条机器指令

T命令,执行一条机器指令

U命令,将内存中的机器指令翻译成汇编指令

4、汇编源程序

  1. 计算2的三次方

    assume cs:abc
    
    abc segment
    mov ax,2
    add ax,ax
    add ax,ax mov ax,4c00H
    int 21H
    abc ends end
  2. 操作内存地址,改变值

    assume cs:abc
    
    abc segment
    
    start:	mov ax,2000H
    mov ds,ax
    mov bx,1000H
    mov ax,[bx]
    inc bx
    inc bx
    mov [bx],ax
    inc bx
    inc bx
    mov [bx],ax
    inc bx
    mov [bx],al
    inc bx
    mov [bx],al mov ax,4c00H
    int 21H
    abc ends end start
  3. 计算2的11次,用loop循环执行

    assume cs:abc
    
    abc segment
    
    start:	mov ax,2
    mov cx,11
    S: add ax,ax
    loop s mov ax,4c00H
    int 21H
    abc ends end start
  4. 循环操作4个单位内存中数据之和

    assume cs:abc
    
    abc segment
    
    start:
    mov ax,1000H
    mov ds,ax mov bx,0000H
    mov al,0011H
    mov ds:[bx],al mov bx,0001H
    mov al,0022H
    mov ds:[bx],al mov bx,0002H
    mov al,0033H
    mov ds:[bx],al mov bx,0003H
    mov al,0044H
    mov ds:[bx],al mov ax,0000H
    mov cx,0004H
    mov bx,0004H
    mov dx,0000H
    S: sub bx,cx
    mov al,[bx]
    add dx,ax
    mov bx,0004H
    loop S mov ax,4c00H
    int 21H abc ends end start
  5. 利用栈交换顺序

    assume cs:abc
    
    abc segment
    dw 0123H,1234H,0252H,12A2H,2222H,3333H,4444H,5555H
    dw 0,0,0,0,0,0,0,0 start:
    mov ax,cs
    mov ss,ax
    mov sp,32
    mov bx,0
    mov cx,8
    S:
    push cs:[bx]
    add bx,2
    loop S mov bx,0
    mov cx,8
    S1:
    pop cs:[bx]
    add bx,2
    loop S1 mov ax,4c00H
    int 21H abc ends end start
  6. 计算a,b两个段数据依次相加的结果存放到c段中

    assume cs:abc,ds:a
    
    a segment
    db 1,2,3,4,5,6,7,8
    a ends b segment
    db 1,2,3,4,5,6,7,8
    b ends c segment
    db 0,0,0,0,0,0,0,0
    c ends abc segment
    start:
    mov ax,a
    mov ds,ax
    mov dx,0000H
    mov cx,8 S: mov bx,dx
    mov ah,ds:[bx]
    add bx,16
    mov al,ds:[bx]
    add ah,al
    add bx,16
    mov ds:[bx],ah
    add dx,1
    loop S mov ax,4c00H
    int 21H
    abc ends end start
  7. 将小写字母转化为大小字母

    assume cs:abc,ds:a
    
    a segment
    db 'BAsiC'
    db 'abcdefgh'
    a ends abc segment
    start:
    mov ax,a
    mov ds,ax mov bx,0 mov cx,5
    S1: mov al,[bx]
    and al,11011111b
    mov [bx],al inc bx
    loop S1 mov bx,5 mov cx,8
    S2: mov al,[bx]
    and al,11011111b
    mov [bx],al inc bx
    loop S2 mov ax,4c00H
    int 21H
    abc ends end start
  8. 把每一个小写字母的前四位转化为大写

    assume cs:code,ds:data,ss:stack
    
    data segment
    db '1. abcdef.......'
    db '2. mnijwq.......'
    db '3. iloveyou.....'
    db '4. oklolp.......'
    data ends stack segment
    dw 0,0,0,0,0,0,0,0
    stack ends code segment
    start:
    mov ax,data
    mov ds,ax
    mov ax,stack
    mov ss,ax
    mov sp,16 mov bx,0
    mov cx,4
    S0: push cx
    mov si,0
    mov cx,4
    S1: mov al,[bx+3+si]
    and al,11011111b
    mov [bx+3+si],al
    inc si
    loop S1 add bx,16
    pop cx
    loop S0 mov ax,4c00H
    int 21H
    code ends end start
  9. cmd窗口中间输入不同颜色和背景的字符串

    assume cs:code,ds:data,ss:stack
    
    data segment
    db 'welcome to masm!'
    db 02h,24h,71h
    data ends stack segment
    dw 8 dup(0)
    stack ends code segment start:
    mov ax,data
    mov ds,ax
    mov ax,stack
    mov ss,ax
    mov sp,10h xor bx,bx
    mov ax,0b872h mov cx,3
    s3: push cx
    push ax
    push bx mov es,ax mov si,0
    mov di,0 mov cx,10h s1: mov al,ds:[si]
    mov es:[di],al
    inc si
    add di,2
    loop s1 mov di,1
    pop bx
    mov al,ds:10h[bx]
    inc bx mov cx,10h
    s2: mov es:[di],al
    add di,2
    loop s2 pop ax
    add ax,0ah pop cx
    loop s3 mov ax,4c00h
    int 21H code ends end start

    结果:

  10. 利用call和ret来实现函数,计算一组数的三次方并保存在内存中

    assume cs:code,ds:data
    
    data segment
    dw 1,2,3,4,5,6,7,8
    dw 0,0,0,0,0,0,0,8
    data ends code segment start:
    mov ax,data
    mov ds,ax mov cx,8
    mov di,0
    s0: mov bx,ds:[di]
    call s
    mov ds:[di+16],ax
    add di,2
    loop s0 mov ax,4c00h
    int 21H s: mov ax,bx
    mul bx
    mul bx
    ret code ends
    end start

最新文章

  1. 苹果mac电脑中brew的安装使用及卸载详细教程
  2. 背水一战 Windows 10 (35) - 控件(弹出类): FlyoutBase, Flyout, MenuFlyout
  3. python类型转换、数值操作
  4. 网络攻防比赛PHP版本WAF
  5. POJ 1696 - Space Ant 凸包的变形
  6. C++:流类库与输入输出
  7. [CFgym101061C]Ramzi(贪心,双条件最短路)
  8. Toy Storage
  9. C语言中数据类型转换的学习
  10. &lt;c:if&gt;判断参数是否同时为空
  11. myeclipse2014安装aptana3.4.0插件
  12. JavaScript学习笔记(二)——选项卡小结
  13. Dinic算法(研究总结,网络流)
  14. CyclicBarrier的使用之王者荣耀打大龙
  15. JSON循环遍历解析
  16. python基础day3
  17. day11.装饰器初识
  18. 《Professional JavaScript for Web Developers》day01
  19. Sqlcmd使用详解
  20. Mac 笔记本 开发日记

热门文章

  1. 905. Sort Array By Parity - LeetCode
  2. 29. Divide Two Integers - LeetCode
  3. c++:-9
  4. drools动态增加、修改、删除规则
  5. JavaScript之parseInt()方法
  6. VTK 截图
  7. 【Spring】事务的执行原理(三)
  8. 利用XtraDiagram.DiagramControl进行流程图形的绘制和控制
  9. js 表面学习 - 认识结构
  10. ConcurrentHashMap深入剖析(基于JDK1.7)