前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >汇编基础

汇编基础

作者头像
Dean0731
发布2020-08-17 20:45:38
1.3K0
发布2020-08-17 20:45:38
举报
文章被收录于专栏:blog-技术博客blog-技术博客

第一章,汇编语言产生

1,机器语言与汇编语言一一对应

2,汇编指令:Mov AX,BX 将寄存器BX,移入AX

3,寄存器:CUP中的存储器,注意不是CUP的缓存,

4,汇编--》编译器---》机器码01

5,汇编语言组成

  • 汇编指令,机器码的助记符
  • 伪指令,编译器执行
  • 其他符号,编译器识别

6,一串机器码,可以使指令,也可以是数据,就看是cd,ds那个指向他

7,地址信息,读或写,数据信息

​ cup与所有内存之间:地址总线,数据总线,控制总线,每条线对应不同信息,指令与数据分开

8,总线

  • 地址总线:产品cpu通过它指定存储单元,地址总线有多少不同信息,就是CPU的寻址范围,64位CPU就是64个地址总线
  • 数据总线:宽度决定传输速度,例如一次传8bit,16bit
  • 控制总线:宽度表示控制能力
image-20200725222259680
image-20200725222259680
image-20200725222458172
image-20200725222458172

9,例

地址:0-7FFFH,为RAM

地址:8000H-9FFFH,为显存地址:当数据写入此处,就会显示

地址:A000H-FFFFH为各个ROM

10,8086CPU如下,8086,8088,龙芯,酷睿等都是类似分配

image-20200725222928292
image-20200725222928292

第二章,寄存器(CPU工作原理)

通用寄存器

1,CPU:运算器,控制器,寄存器,内部总线相连接

2,8086cpu寄存器:共14个,有8个通用寄存器

  • AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW
  • 所有寄存器16bit,16位的CPU,8086上一代8bit
  • AX,BX,CX,DX通用寄存器,可以分为两个独立的8位寄存器使用 AX-->AH,AL
image-20200725224609858
image-20200725224609858
image-20200725224111847
image-20200725224111847
image-20200725224232240
image-20200725224232240
image-20200725224722314
image-20200725224722314

寄存器中数据大多是n*8bit

汇编指令

image-20200725225400234
image-20200725225400234

物理地址

16位结构CPU

1,一次16bit数据

2,寄存器最大宽度16bit

3,寄存器运算器之间通路16bit

8086CPU给出物理地址

1,20位地址总线,寻址1m

2,内部16位结构,寻址64kb

方法:

image-20200725232114587
image-20200725232114587

3,物理地址=段地址*16+偏移地址 因为是2进制

1,内存并没有分段,分段是因为cup,内部不足,但因此使用分段管理内存

2,偏移地址16bit,因此每段64KB

3,CUP可以不痛段地址与偏移构成相同的物理地址

段寄存器

8086:CS,DS,SS,ES

cs:指令段寄存器,ip指令偏移寄存器 ----》段,偏移

image-20200725235034031
image-20200725235034031

修改CS,IP

1,只能操作寄存器控制cpu,因此需要控制cs,ip

2,mov 传送指令,可修改ax,但不能cs,ip

3,jmp 2ae3:3 跳转的意思 此时cs 为2ae3,ip为3

代码段

将n<64kb的数据 ---》代码段

将cs,ip指向该代码段,会认为是指令,才会执行,执行后ip = ip + 指令长度

image-20200726003309179
image-20200726003309179

第三章,寄存器

内存中的存储

1,例:数字2000 (4E20H)

image-20200726131206580
image-20200726131206580

任何两个连续单元,N,N+1,可以看做两个内存单元,也可以看做地址为N的字单元中的高位字节单元,低位字节单元

DS与Address

DS:存放的数据的段地址,

1,执行指令时,自动取DS中数据为内存单元的段地址

2,mov al,[0] 将ds:0 内存单元中的数据移入al

3,但不能直接把值移入ds ,mov ds 1000H:错误的 8086cpu不支持放入段寄存器,硬件问题。只能数据 --》通用寄存器--》段寄存器

image-20200726133154156
image-20200726133154156

字的传送

mov,add,sub

1,mov

  • mov 寄存器,数据
  • mov 寄存器,寄存器
  • mov 寄存器,内存
  • mov 内存,寄存器
  • mov 段寄存器,寄存器
  • mov 寄存器,段寄存器 ,也可以
image-20200726140431689
image-20200726140431689

数据段

push ax:将ax放入栈内存中

​ sp =sp-2

​ ss:sp 指向新地址

pop ax:从栈内存取数据到ax

1,cup如何知道某段内存是栈内存?

ss,栈顶段寄存器,sp栈顶偏移 ss:sp指向栈顶,栈为空时指向栈顶下一位,

出栈时只是修改索引,数据还未覆盖,由此可见,硬盘类似

2,cpu如何知道哪个是栈顶,栈底?从大地址向小地址写数据

3,语言中的函数,调用时就是申请一块栈内存,执行完,栈内存元素全部出栈,因此局部变量失效,栈内存由编译器管理,堆内存有程序员管理

栈顶越界

1,cpu关心栈只关心栈顶指针在何处,当前要执行的指令是哪个

2,c,c++常会溢出

POP,PUSH

1,栈空间,一段固定读取格式的内存

栈段

1,可以将小于64kb的内存当做栈

2,认为10010H,1001FH 当做16字节栈,但cup只关心栈顶,不会关心栈段的大小

第四章,第一个程序

汇编---》可执行

1,流程

  • 编写,
  • 编译程序(masm.exe),产生目标文件
  • 连接程序(link.exe),生成可执行文件

2,可执行程序组成

  • 程序,数据(程序中定义的数据)
  • 描述信息,程序多大,占空间多大等

3,执行过程

  • 按照可执行文件描述信息,将程序,数据加载到内存,设置cs,ip等

4,汇编指令,伪指令

  • segment .... ends:定义一个段,程序段,数据段等,一个程序有多个段
  • end:便已结束标记
  • assume:假设,将段指定为数据段,程序段等,伪指令指向程序开始等等
    • assume cs:codesg codesg segment start: mov ax 0123H codesg ends end
image-20200726160028404
image-20200726160028404

源程序

1,一个标号只带一个地址

2,codesg:给段的命名,最后会变为地址

3,程序返回,

  • 返回使它运行的那个程序
    • mov ax,4c00H
    • int 21H
    • 这两个规定的语句实现中断

编辑源程序

assume cs:abc
abc segment
	mov ax,2
	add ax,ax
	add ax,ax
	mov ax,4c00H
	int 21H
abc ends
end

masm 编译,link 链接 生成exe文件

“;”可以简化masm,link

ml:两部合起来

# 有入口的文件
assume cs:abc
abc segment
start:mov ax,2
	add ax,ax
	add ax,ax
	mov ax,4c00H
	int 21H
abc ends
end start

1,exe文件加载过程

image-20200726181347006
image-20200726181347006

程序加载后,内存地址为ds:0

其中前256是dos与程序通信的,256向后是程序

第五章,bx与loop

注意:在debug中[0]表示段地址的偏移地址,在masm中表示数值0

bx

mov bx ,0

mov ax,[bx] ,此时[bx]表示以bx内容位偏移地址

1,将bx中的数据作为偏移地址

inc bx # 自加

loop

1,loop 标号

  • cx = cx-1
  • 判断cx中的值,不为零转到标号执行处,若果为零则向下执行
  • cx中存放的一般是循环次数

2,2^1000

assume cs:code
code segment
mov ax,2
mov cx,11
s:add as,ax
loop s # s就是标号   判断cx,是否跳到标号

3,越位赋值会可能出错 mov ax,[bx]

mov al,[bx]

mov ah,0

4,汇编语言中数字以字母开头,例如大于9fffh的,Afffh,需要在前边加0

5,使用deubg追踪循环

g 命令地址:相当于 debug中的段点

p :在循环时使用,会直接跳到循环结束,即自动完成循环过程

注意

在masm中

mov al,[0] 将0移入al

mov al,ds:[0] ,偏移为0的地址中内容放入al

mov al,[bx],将bx为偏移地址的地址中的内容放入al

mov al,ds:[bx],同上

loop,bx联合应用

内存数值相加时的问题

例:ffff:0---ffff:b 12个字节相加,

问题:放入16位ax,会不会越界,8位如何放入16位寄存器

解决方法:使用中介,将8位数据放入16位中介寄存器ax,再相加

assume cs:code
code segment
	mov,ax,0ffffh
	mov,ds,ax # 设置段地址
	
	mov dx,0 # 初始化累加寄存器
	mov al,ds:[0]  # 赋值给中间寄存器
	mov ah,0 # 设置高位为0,此时ax为0
	add dx,ax # 累加
	...
	mov ax,4c00h
	int 21h

\(sum =\sum\limits_{X=0}^{0bh}(ffffh*10h+X)\)

# 优化:使用循环,偏移地址应该递增
asume cs:code
code segment
	mov ax,0ffffh
	mov ds,ax
	mov bx,0
	
	mov dx,0
	
	mov cx,12
	
s:	mov al,[bx]
	mov ah,0
	add dx,ax
	int bx
	loop s
	mov ax,4c00h
	int 21h
code ends
end

段前缀

ds就是段地址,也称为段前缀,ds是默认的段前缀,其他还有cs,es等

一段安全的空间

在PC中,0:200到0:2ff是安全的空间

段前缀的使用

在不同的段中操作时,一个ds需要多次更改,可能需要多个段寄存器,例如用es替代。效果更好

第六章,包含多个段的程序

代码段中使用数据

dw 0123h,0456h 定义字符型数据

db 45h,78h 定义字节型数据

当上面定义在cs中时,数据段地址就是代码段的段地址

dw在第一行定义,数据地址偏移为0,2,4,6....

assume cs:code
code segment 
	dw 0123h,0456h,0789h
	start:mov bx,0
	mov ax,0
	mov cx,0
	s:add ax,cs:[bx]
	add bx 2
	loop s
	mov ax 4c00h
	int 21h
code ends
end start
# cup读指令的时候会从start开始,若不添加start,应为dw的存在,存放的是数据,无法转化为机器指令,程序无法执行
# end的作用:通知编译器程序结束,告诉编译器程序入口在哪里,当不指定入口时,会按照上到下执行,因此若现定义数据,会把数据当做指令执行

代码段中使用栈

问题:将上面程序中的数据逆序存放

assume cs:code
code:segment
	dw 0123h,0456h,0789h
	dw 0,0,0 # 定义数据当做栈空间
	
	start :mov ax,cs
	mov ss,ax   # 指定栈段
	mov sp,32	# 指定栈偏移,栈指针,操作时指针自动变
	mov bx,0
	mov cx,3	# 循环次数
	
	s:push cs:[bx] # 入栈数据
	add bx,2
	loop s
	
	mov bx,0
	mov cx,3
	
	s0:pop cs:[bx]
	add bx,2
	loop s0
	
	mov 4c00h
	int 21h
code ends
end start

将数据,代码,栈放入不同的段

上面的逆序排放

assume cs:code,ds:data,ss:stack
data segment
	dw 0123h,0456h,0789h
data ends
stack segment
	dw 0,0,0
stack ends
code segment
start:mov ax,stack  # cs,ss,da 系统加载程序时会有系统指定加载的位置,cs 确定后,ds应该就是cs-2,ss=cs-1
	  mov ss,ax
	  mov sp,6  # 指定栈指针
	  mov ax,data 
	  mov ds,ax # 数据段地址
	  
	  mov bx,0
	  mov cx,3
	  
	  s:pop [bx]
	  add bx,2
	  loop s
	  
	  mov bx,0
	  mov cs,8
	  s0:pull [bx]
	  add bx,2
	  loop s0
	  
	  mov ax,4c00h
	  int 21h
code ends
end start

第七站,更灵活的定位内存地址的方法

and和or指令

  • and
    • 两个都是1为1,其他是0 ,add al 10100010B
    • 可以把寄存器某一位设置为0:and al,10111111B
  • or
    • 有一个1就为1
    • 使得寄存器某一位为1:or al,00000100B

关于ASCII

键盘按下a键:键盘产生61h,放入内存空间,编辑器软件从指定内存读取,送到显存中

以字符形式给出的数据

'....'指明数据是以字符形式给出,编译器会转化为ASCII

assume ds:data
data segment
db 'unix'  # db 75H,6EH,49H,58H
db 'fork' # ...
data ends
code segment
start:mov al,'a' # mov al,61h
	mov b1,'b'
	mov ax,4c00h
	int 21h
code ends
end start

大小写转化问题

A:65,a:97

大写:第五位为0

小写:第五位为1

and 小写,11011111b

or 大写,00100000b

[bx+idata]

mov ax,[bx+200]:将地址内数据放入ax,这个地址是bx中的值+200

mov ax,200[bx] mov ax,[bx].200

用[bx+idata]方式进行数组的处理

assume cs:code,ds:data
data segment
	db 'BaSiC'
	db 'MinIX'
data ends

code segment
start:mov as,data
	mov ds,ax
	mov bx,0
	
	mov cx,5
	s:mov al,[bx]
	and al,11011111b
	mov [bx],al
	
	mov al,[5+bx]   # 5[bx]
	or al,00100000b
	mov [5+bx],al
	
	inc bx
	loop s

code ends
end start

SI和DI

与bx类似的功能,但不能分为2个8位的使用,

bx不够用的问题

# 将数据复制到后边地址
# ds:si 指向原数据
# ds:di 指向目的地址
assume cs:code,ds:data
data segment
	db 'welcome to masm!'
	db '...............'
data ends

code segment
start:mov ax,data
	mov ds,ax
	mov si,0
	mov di,16
	mov cs,8
	s:mov ax,[si]
	mov [di],ax
	add si,2
	add di,2
	loop s
	
	mov ax,4c00h
	int 21h
code ends
end start

[bx+si]和[bx+di]

两个功能类似

[bx+si] 表示一个内存单元,偏移地址为bx值+si值

[bx+si+idata]和[bx+di+idata]

表示内存单元,偏移地址,

不同寻址方式的灵活应用

  • ds:[idata]
  • [bx]
  • [bx+idata]
  • [bx+si]
  • [bx+si+idata]

例:将数据段单词,开头变为大写

assume cs:code,ds:data
data segment
db '1.file    '
db '2.editable'
db '3.help    '
data ends
code segment
start:	mov ax,data
		mov ds,ax
		mov bx,0
		
		mov cx,3
	s:mov al,[bx+2] # 把第二个字母放入al
 	add al,11011111b  # 修改字母,变为大写
	mov [bx+3],al 	# 放回
	add bx,10
	loop s
	mov ax,4c00h
	int 21h
code ends
end start

对于多层循环,需要其它寄存器记下外层cx的值,内层循环结束后恢复,不然会遇到死循环

当寄存器不够时,需要使用内存了,如使用栈,每层cx入栈 push cx,结束时出栈pop cx

数据处理的基本问题

引言

  • 处理的数据在哪里
  • 处理的数据有多少,多长

寄存器:ax,bx,cx,dx ah,al,bh,bj,ch,cl,dh,dl

sp(栈指针),bp, si(原数据地址),di(目的数据地址)

段寄存器:ds(数据段),ss(栈段),cs(代码段),es(扩展段)

bx,si,di,bp

  • 8086可以用[...]表达内存地址的寄存器:bx bp si di,[ax]是错误的
  • 这几种不能任意组合
    • bx,si
    • bx,di
    • bp,si
    • bp,di
    • 其他的组合是错误的,例如:mov ax,[bp+si]
  • 在[...]使用bp,时段地址是ss,即bp就像是sp

机器指令处理的数据所在位置

指令执行前,数据所在位置:CUP,内存,端口

汇编中数据位置的表达

  • 立即数:直接包含在机器指令中的数据,存在于指令缓冲区:mov ax,1 :b80100
    • B8表示移动立即数到ax
    • 指令寄存器:
      • 就是cpu读取一条指令
      • 经过数据总线条指令存出入指令缓冲器
      • 读取该指令要操作的数据,放入地址加法器
      • 数据放入目的地址
  • 寄存器 mov ax,bx:89D8
  • 段地址和偏移地址
    • mov ax,ds:[bp] 强制改变段地址

寻址方式

image-20200808154051203
image-20200808154051203

指令要处理的数据有多长

8086可操作byte,word,在机器指令中需要指明进行操作的是字符还是字节

  • 通过寄存器指名要处理的数据
    • mov ax,bx
  • X ptr指明内存长度
    • mov word ptr ds:[0],1
    • inc word ptr [bx]
    • inc word ptr ds:[0]
    • add word ptr [bx],2
    • mov byte ptr ds:[0],1
    • 等等,
  • 其他
    • 栈指令,操作时,默认都是按照字符操作

寻址方式的总和应用

  • 字符串在内存中就是数组
  • 一般用[bx+idata+si]访问结构体
    • bx表示结构体
    • idata表示某一个数据项
    • si表示数据项中每个元素
    • student.name[i]

divide指令

  • 除数:8位,16位,寄存器,内存都可以
  • 被除数:默认ax,dx与ax
    • 除数8位,被除数16位(dx)
    • 除数16位,被除数应该是32位(dx+ax)
  • 指令格式
    • div 寄存器
    • div 内存单元
      • div byte ptr ds:[0]
        • al = ax/0地址的商
        • ah = ax/0地址余数
      • div word ptr es:[0]
        • ax = [(dx)*10000H+(ax)]/((ds)*16+0)的商
        • dx = [(dx)*10000H+(ax)]/((ds)*16+0)的余数
      • div byte ptr [bx+si+8]
        • al = (ax)/((ds)*16+bx+si+8)的商
        • ah = (ax)/((ds)*16+bx+si+8)的余数
      • div word ptr [bx+si+8]
        • ax = [dx*10000h+ax]/(ds*16+bx+si+8)的商
        • dx = [dx*10000h+ax]/(ds*16+bx+si+8)的余数
      • 最后结果覆盖原来被除数的位置

伪指令dd

  • 定义dword,即double word
  • data segment db 1 # 01H dw 1 # 0001H dd 1 # 00000001H data ends

dup

  • 同dw,dd,db一样有编译器识别处理的符号,用来数据重复
  • db 3 dup(0) # 定义了3个字节0 db 0,0,0 db 3 dup(0,1,2) db 0,1,2,0,1,2,0,1,2 db 2 dup('abc,'ABC) db 'abcABCabcABC' stack segment dw 0,0,0,0,0,0... stack ends stack segment db 200 dup(0) stack ends

第九章,转移指令的原理

8086CPU转移指令分类

  • 无条件转移指令 例jmp
  • 条件转移指令
  • 循环指令 例loop
  • 过程
  • 中断

操作符offset

由编译器处理的符号,取得标号的偏移地址吗,就标号所在地址

assume cs:code
code segment
	start:mov ax.offset start  # 相当于mov ax,0
	s:mov ax,offset s # 相当于mov ax,3
code ends
end start

jmp指令

  • cs,ip
    • 可以只修改ip
    • 也可以修改cs
  • 转移要求
    • 目的地址
    • 转移的距离 (-128----》127)段内跳转
      • jmp start 标号

依据位移进行jmp指令

movax,0123 		# B8 23 01
mov as,ds:[0123]# A1 23 01
push ds:[0123]	# FF 36 23 01

jmp指令对应的机器码中没有目的地址,是相对于jmp所在指令的偏移

  • jmp near ptr 标号 实现段内近转移:
    • IP=IP+16位位移
    • near ptr 指明此处为16位位移,进行的是段内近转移
    • 16位位移 = 标号处地址减去jmp指令后第一个字节地址

转移的目的地址在指令中的jmp指令

  • 偏移地址是实际的地址
  • 段间转移,远转移
  • jmp fat ptr 标号:修改了cs:ip ---->EAXXXXYYYY

转移地址在寄存器中的jmp指令

jmp 16位寄存器

jmp ax

转移地址在内存中的jmp指令

  • jmp word ptr 内存
  • jmp dword ptr 内存,段之间转移,32位 高16位cs,低16位ip

jcxz指令

  • 有条件转移
  • (-128--127)
  • 机器码包含位移,而不是目的地址
  • jcxz 标号,
    • cx=0 跳转,否则不跳转,向下执行
    • ip = ip+8位移
      • 负数用补码表示
      • 有编译时编译器算出

loop指令

  • 位移而不是目的地址
  • -128--127
  • 与cx配合
  • 都是编译器指令

根据位移进行转移的意义

使用位移可使程序在内存中任意位置调用

编译器对转移位移超界的检测

编译时编译器会报错

注:

显存地址:B8000H-BFFFFH dos系统的显存地址

第十章,Call和Ret指令

都是修改cs,ip

ret与retf

  • ret使用栈中的数据,修改ip实现近转移
  • cpu执行ret时
    • ip=ss*16+sp
    • sp=sp+2
  • cpu执行retf时
    • ip=ss*16+sp
    • sp=sp+2
    • cs=ss*16+sp
    • sp=sp+2
  • ret执行后 ip=0,cs:ip指向代码段第一条指令
  • retf执行后,cs:ip指向代码段第一条指令

call

  • 与ret配合使用
    • 将ip,或cs,ip入栈
    • 转移(jmp)
  • 不能短转移

位移转移的call

  • 将当前标号入栈后,转到标号处执行
    • sp =sp -2
      • ss*16+sp=ip
    • ip = ip+16位位移
  • 相当于进行push ip,jmp near ptr 标号

直接地址转移的call

call far ptr 标号
sp = sp -2
ss*16+sp=cs
sp = sp -2
ss*16+sp=ip

cs=标号所在段地址
ip=标号所在偏移地址

相当于push cs,push ip,jmp fat ptr 标号

寄存器转移的call

sp =sp -2

ss *16+sp =ip

ip=16位寄存器

相当于push ip,jmp 16位寄存器

转移地址在内存的call

  • call word ptr 内存
    • push ip
    • jmp word ptr 内存单元
  • call dword ptr 内存
    • push cs
    • push ip
    • jmp dword ptr 内存单元

call与ret的配合使用

可以使用call与ret配合写子程序,就像是高级语言中的方法,使用call跳转,ret返回

mul

  • 乘法指令
    • 相乘的2位数位数需要相同
    • 8位:AL中和8位寄存器或内存单元
    • 16位:AX中和16位寄存器或内存单元
  • 结果
    • 2个8位:放在ax
    • 2个16位:高位DX,低位AX
  • mul reg,mul 内存单元
    • mul byte ptr ds:[0] ==(ax)=(al)*(ds*16+0)
    • mul word ptr [bx+si+8]
      • (ax)=(ax)*((ds)*16+(bx)+(si)+8) 低8位
      • (dx)=(ax)*((ds)*16+(bx)+(si)+8) 高8位
  • 例100*10
    • mov al,100
    • mov b1,10
    • mul bl
    • ax = 1000(03E8H)
  • 100*10000
    • mov ax,100
    • mov bx,10000
    • mul bx
    • ax=4240H
    • dx=000FH

模块化程序设计

如何存储子程序参数,与返回值

  • 子程序计算N的3次方
    • N存储位置
      • 寄存器
    • 结果存储位置
      • dx,ax
    • bx = N ;型参 dx:ax=N^3 cube:mov ax,bx mul bx mul bx ret

参数和结果传递问题

用寄存器存储参数与结果最常用的方法

批量数据传递

传递的数据多的时候怎么办?使用内存,或者栈,高级语言就是栈

assume cs:code
data segment
	db 'conversation'	
data ends
code segment
start:mov ax,data
	mov ds,ax
	mov si,0	;ds:si指向字符串所在空间首地址
	
	mov cx,12	;cx存放字符串长度
	call capital
	
	mov ax,4c00h
	int 21h
capital:and byte ptr [si]:11011111b
	inc si
	loop capital
	ret
code ends
end start

寄存器冲突

上面的程序,当不知道字符串长度时,如何做

db 'conversation','0'

capital:mov cl,[si]
	mov ch,0
	jcxz ok	;若果cx=0,结束,若不是,接着处理
	and byte ptr [si],11011111b
	inc si
	jmp short capital
ok:ret

第十一章,标志寄存器

引言

计算机中的数据可以看做是有符号数,也可以是无符号数

00000001B # 可看做无符号数1,或有符号数+1
10000001B # 可看做无符号数129,或有符号数-127

flag标志寄存器与其它不同,其他是用来存放数据的,flag是按位起作用

image-20200814142743401
image-20200814142743401
image-20200814163851014
image-20200814163851014

1,3,5,12,13,14,15在8086中没有使用

ZF,零标志位

  • 上一条指令结果为0,此时标志位ZF=1
    • mov ax,1
    • sub ax,1
    • 此时ax=0
  • 否则ZF=0
    • mov ax,2
    • sub ax,1
    • ax=1
  • add,sub,mul,inc 等等都是运算指令,mov push等都是传送指令

PF,奇偶标志位

  • 指令执行后,结果中所有二进制中1的个数
    • 偶数,PF=1
    • 奇数,PF=0

SF,符号标志位

  • 指令执行后结果的正负情况
  • SF=1,结果为负
  • SF=0,结果为正
  • mov al,10000001B add al,1 ;结果 al=100000010B ;有符号位 -12 6 ;无符号位 130 ;所以说该指令包含结果有2个
    • SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据正负,Cpu会影响SF标志位,但Cpu并不识别数据有无符号
  • 但我们把数据当做无符号数,SF则无实际作用
    • mov al,10000001B add al,1 ;结果为10000010B,SF=1 ;如果指令是进行有符号运算,那么结果为负数,否则不用处理 ;注意没有-0的说法,只有+0

CF,进位标志位

存储上一条指令执行后是否有数据进位,或借位(减 法)

  • 有进位 CF=CY=1
  • 无进位 CF=NC=0

减法

  • 97H-98H 在计算机中就是
  • 197H-98H = FF,CY=1

OF,溢出标志位

超出了机器的范围

  • 溢出是针对有符号位,正+正边负
  • 进位是相对于无符号位,例如8位边9位
  • 溢出时OF=OV=1

对于cpu的计算结果,若做有符号位观察,OF,SF,若看作无符号位观察CF

总之,cpu计算时,不管有无符号,adc指令:结合符号位获取正确值

mov ax,98d ; 0110 0010
add ax,99d ; 0110 0011

;1100 0101  C5 SF=1,OF=1,CF=0
;当做无符号位相加,C5
;当有符号位,首位为1,SF=1表示是负数,是-59的补码,

adc指令

带进位加法指令,利用CF位记录值

adc ax,bx ax = ax+bx+CF

add,配合adc可以解决这些问题

;1EF000h+201000h 高16位ax,低16位bx
mov ax,001EH
mov bx,0f000H
add bx,1000H ; 0000H cf=1
adc ax,0020H ; 

adc执行后也会可能产生进位

;1E F000 1000h+ 20 1000 1EF0h 高位16ax,次高位16bx,cx低16位
;思路 低16位相加,然后次16位adc,高16位adc
mov ax,001EH
mov bx,0f000H
mov cx,1000H

add cx,1ef0h
adc bx,1000h
adc ax,0020h

更大的数据可以放在栈或内存中

sbb指令

带位减法指令

sbb ax,bx = > ax= ax-bx-cf

与加法类似

cmp指令

相当于减法指令,但不保存结果,仅仅对标志位进行设置

cmp ax,ax ===> 此时ax不变,仅影响flag ---》ZF=1,PF=1,SF=0,CF=0,OF=0

image-20200814182305437
image-20200814182305437

有符号位比较

ZF

需要考虑OF,SF

  • OF=0,SF=1 AH<BH
  • OF=1,SF=1 AH>BH
  • SF=0,OF=1 AH<BH
  • OF=0,SF=0 AH>BH

检测比较结果的条件转移指令

与cmp配合

image-20200814233016395
image-20200814233016395
cmp ah,bh
je s
add ah,bh
jmp short ok
s:add ah,ah
ok:ret

DF标志和串传送指令

  • flag第10位,方向标志位
  • 在串指令中,控制每次操作后si,di增减
  • DF=0,每次操作后递增
  • DF=1递减
  • movsb:以字节为单位传递,将ds:si指向的内存中的数据送入es:di
    • es*16+di=ds*16+si
    • 若DF=0,SI=SI+1,DI=DI+1
    • 若DF=1;SI=SI-1,DI=DI-1
  • movsw 以字为单位传送,即16位,si,di每次加减2
  • movsb,movsw与rep配合
    • rep movsb ,根据cx的值重复n次
  • cld:设置DF=0,std设置DF=1
  • assume cd:code data segment db 'welcome to masm!' db 16 dup(0) data ends code segment start:mov cx,16 cld; mov ax data mov ds,ax mov si,0 mov di,16 mov es,ax rep movsb mov ax,4c00h int 21h code ends end start

pushf和popf

pushf:将标志寄存器的值压入栈中

popf:弹出到标志寄存器,出栈

第十二章,内中断

内中断的产生

外部中断:外部设备

内部中断:内部错误

软件中断,int 21h等

CPU中断优先权:

  • 除法错误,溢出中断,软件中断
  • 不可屏蔽中断
  • 可屏蔽中断
  • 单步中断

中断处理程序

内存中有中断处理程序

中断向量表

  • 形式:序号 中断程序地址
  • 地址用8bit,所以一共256个中断程序
  • int 序号 就会调用中断处理程序
  • 对于8086CUP,中断程序地址存放位置0000:0000---》0000:03FF,段地址16bit,偏移地址16bit,32*256
  • 8086中0:200-0:300安全的地址,因为并不是256个程序都要用

中断过程

找到中断程序地址,CPU设置cs,ip该过程为中断过程

中断过程:

  • 取得中断类型码
  • 标志寄存器入栈
  • 设置标志寄存器的第八位TF,第九位IF为0
  • CS,IP入栈
  • 读入cs,ip

中断处理程序

  • 保存用到的寄存器
  • 处理中断
  • 恢复寄存器
  • 用iret指令返回

iret:pop ip;pop cs;popf

iret和硬件自动完成中断过程配合使用

除法错误中断处理

编程处理0号中断

发生除法溢出时,即结果比寄存器范围大,Cpu将转换为处理中断程序

中断向量表中该错误终端地址为0号地址

可以自定义中断程序,修改中断向量表,此时会执行自己的中断程序

assume cs:code
code segment
start:
	mov ax,cs
	mov ds,ax
	mov si,offset do0;设置自定义终端程序位置
	mov ax,0
	mov es,ax
	mov di,200h	;设置es:di位置
	
	mov cx offset do0end- offset do0
	cld rep movsb ;中断程序写入内存
	;设置中断向量表
	mov ax,4c00h
	int 21h
do0:
	xxxxx
	mov ax,4c00h
	int 21h
do0end:nop ;占一个字节,无作用
code ends
end start

单步中断

CPU在执行一条指令后检测到TF=1,就会引发中断过程

单步中断的类型码为1,debug就是改变了1号中断的程序,改为debug的程序

响应中断的特殊情况

有时候遇到中断信号CPU也不会响应,

例如:

  • SS:SP的设置过程,ss,sp需要同时改变,因此不能被中断
    • mov设置ss:sp时也要连续

第十三章,int指令

int指令

与call类似,int调用中断程序

对int,iret与栈的深入理解

BIOS与dos中断例程的安装

  • 开机后CS:0FFFFH,IP=0, 该位置有一条跳转指令,执行后专区bios的硬件检测与初始化程序
  • 初始化程序,将BIOS所支持的中断向量,即Bois提供的中断例程入口记录在中断向量表
  • 完成后 int 19h进行操作系统的引导,将计算机交给操作系统
    • dos病毒就是改变 int 19h的中断

BIOS中断历程应用

  • int 10h中断的设置光标位置功能
    • 10h中包含多个子程序,通过ah,设置子程序的序号

    mov ah,2 ;2号子程序 mov bh,0 ;0页 mov dh,5 ;5行 mov dl,12 ;12列 int 10h

  • int 21h
    • 程序返回功能
      • mov ah 4ch # 序号,程序返回的功能
      • mov al,0 # 返回值
      • int 21h
    • 光标显示字符功能

第十四章,端口

端口的读写

  • 访问内存
    • mov ax,ds:[8]
    • cpu 通过地址线将地址8信息发出
    • cpu控制线发出内存读命令,选中存储器新编,通知他读数据
    • 存储器将8单元数据通过数据线送入cpu
  • 当问端口
    • 使用in,out
    • in al,60h
    • 地址总线60h发出
    • 控制线发出端口度命令,端口芯片,通知读数据
    • 端口芯片通过数据线传入cpu
    • 8位端口al,16位ax
      • in al,20h 读取20h端口一个字节
      • mov dx,3f8h
      • in al,dx 读取改端口一个字节

CMOS RAM 芯片

  • 包含一个实时钟和128存储单元的RAM
  • 该芯片靠电池供电,不是电源
  • 128单元中,内部时钟占用0-0dh,其他保存系统配置信息
  • 芯片内部有2端口70h,71h,cup通过他们进行读写
    • 70h地址端口,要访问的RAM单元地址,
    • 71h是数据端口,要读取或写入的数据
    • 例:读取RAM 2号单元
      • 2送入 70h
      • 从71 读取2单元内容

shl与shr指令

  • 逻辑移位指令,左移与右移
  • 将寄存器或内存单元中数据左移,右移
  • shl
    • 数据左移
    • 最后移出的写入CF
    • 最低位0补充
    • 若移位大于1,移动位数放在cl,不能直接用数字
    • mov al,01001000b shl al,1 ;al = 10010000b
  • shr 相反的操作

CMOS RAM中存储时间信息

  • 秒00H,分02h,时04h,日07h,月08h,年,09h
  • BCD格式码存放
    • 四位01表示1-9
    • 0000-0,0001-1,0010-2 ..... 1001-9
    • 例如26:0010 0110

第十五章,外中断

接口芯片和端口

外设的出入不是直接送入内存,而是相关接口芯片的端口中

外中断信息

  • 可屏蔽
  • 不可屏蔽
  • 需要看IF位,IF=1,指令执行后中断,否则不中断
  • sti设置TF=1,cli if=0
  • 不可屏蔽类型码固定是2
    • 标志位入栈,IF=0,TF=0,表示此程序不能被中断
    • cs,ip入栈
    • ....
  • 外设几乎都是和屏蔽中断

PC键盘的处理过程

  • 按下一个键
  • 键盘芯片产生扫描码
image-20200815161038632
image-20200815161038632
  • 送入主板接口芯片寄存器,寄存器端口60h
  • 松开时也会送入
  • 到达60h时,发送int 9 中断
  • Bios int9中断例程,
    • 读取60h端口扫描码
    • 是字符,将扫描码与ascii送入bios键盘缓冲区(因为有些操作在操作系统之前),缓冲区中 一个按键16位 8位扫描码,8位ASCII
    • 是控制键,转换为状态字节,写入内存中存储状态的字节单元
  • cpu检测到,若IF=1,引发中断去执行int9

编写int 9 中断例程

安装新的int 9终端例程

第十六章,直接定址表

描述了单元长度的标号

assume cs:code
code segment
a:db 1,2,3,4,5,6,
b:dw 0
start :mov si,offset a;将a的偏移地址给si
code ends
end start
;若标号后边没有“:”他们可以同时描述内存地址与单元长度

在其他段中使用数据标号

有“:"的地址标号只能在代码段使用

若要使用数据标号访问数据,需要assume 将寄存器与段对应

例如上面的数据,访问12345678中的1 需要设置ds,si

若使用a,则mov ax,[0]即可不用管ds,因为assume ds:data

  • 存储地址
    • data segment a db 1,2,3,4,5,6,7,8 b dw 0 c dw offset a,seg a,offset b,seg b ; c dd a,b ;32bit存储地址 data ends

直接定址表

程序入口地址的直接定址表

第十七章,BIOS键盘的输入磁盘读写

int 9 中断对键盘输入的处理

键盘缓区15个字单元,存储扫描码,ascii

int 16 读取键盘缓冲区

mov ah,0
int 16h 
;从键盘缓冲区读取一个,并删除它
; ah=扫描码,al=Ascii

int 16h的0号功能

  • 检测缓冲区是否有数据
  • 没有继续上一步
  • 读取缓冲区第一个字
  • 送入ax
  • 缓冲区已读取那个字删除

int 9向缓冲区写数据,int16h读数据,编程接受用户输入时,就是int16h

字符串的输入

  • 要求
    • 能够输入
    • 输入时显示
    • 可以删除
  • 使用栈

int 13h

柱面号,磁道号,扇区号

读取:

ah = int 13h ;功能号,2表示读取,3表示写入
al=读取扇区数
ch=磁道号
cl=扇区号
dh=磁头号
dl=驱动号 0:软驱A,1:软驱B   80h:硬盘C,81h:硬盘D
ex:bx 向此区域读入数据

ah=0,al = 读入的扇区数
ah=出错代码

写入同上

  • 直接写入可能覆盖数据,危险
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一章,汇编语言产生
  • 第二章,寄存器(CPU工作原理)
    • 通用寄存器
        • 汇编指令
          • 物理地址
            • 16位结构CPU
              • 8086CPU给出物理地址
                  • 段寄存器
                    • 修改CS,IP
                      • 代码段
                      • 第三章,寄存器
                        • 内存中的存储
                          • DS与Address
                            • 字的传送
                              • mov,add,sub
                                • 数据段
                                    • 栈顶越界
                                      • POP,PUSH
                                        • 栈段
                                        • 第四章,第一个程序
                                          • 源程序
                                            • 编辑源程序
                                            • 第五章,bx与loop
                                              • bx
                                                • loop
                                                  • 注意
                                                    • loop,bx联合应用
                                                      • 段前缀
                                                        • 一段安全的空间
                                                        • 第六章,包含多个段的程序
                                                          • 代码段中使用数据
                                                            • 代码段中使用栈
                                                              • 将数据,代码,栈放入不同的段
                                                              • 第七站,更灵活的定位内存地址的方法
                                                                • and和or指令
                                                                  • 关于ASCII
                                                                    • 以字符形式给出的数据
                                                                      • 大小写转化问题
                                                                        • [bx+idata]
                                                                          • 用[bx+idata]方式进行数组的处理
                                                                            • SI和DI
                                                                              • [bx+si]和[bx+di]
                                                                                • [bx+si+idata]和[bx+di+idata]
                                                                                  • 不同寻址方式的灵活应用
                                                                                  • 数据处理的基本问题
                                                                                    • 引言
                                                                                      • bx,si,di,bp
                                                                                        • 机器指令处理的数据所在位置
                                                                                          • 汇编中数据位置的表达
                                                                                            • 寻址方式
                                                                                              • 指令要处理的数据有多长
                                                                                                • 寻址方式的总和应用
                                                                                                  • divide指令
                                                                                                    • 伪指令dd
                                                                                                      • dup
                                                                                                      • 第九章,转移指令的原理
                                                                                                        • 操作符offset
                                                                                                          • jmp指令
                                                                                                            • 依据位移进行jmp指令
                                                                                                              • 转移的目的地址在指令中的jmp指令
                                                                                                                • 转移地址在寄存器中的jmp指令
                                                                                                                  • 转移地址在内存中的jmp指令
                                                                                                                    • jcxz指令
                                                                                                                      • loop指令
                                                                                                                        • 根据位移进行转移的意义
                                                                                                                          • 编译器对转移位移超界的检测
                                                                                                                            • 注:
                                                                                                                            • 第十章,Call和Ret指令
                                                                                                                              • ret与retf
                                                                                                                                • call
                                                                                                                                  • 位移转移的call
                                                                                                                                    • 直接地址转移的call
                                                                                                                                      • 寄存器转移的call
                                                                                                                                        • 转移地址在内存的call
                                                                                                                                          • call与ret的配合使用
                                                                                                                                            • mul
                                                                                                                                              • 模块化程序设计
                                                                                                                                                • 参数和结果传递问题
                                                                                                                                                  • 批量数据传递
                                                                                                                                                    • 寄存器冲突
                                                                                                                                                    • 第十一章,标志寄存器
                                                                                                                                                      • 引言
                                                                                                                                                        • ZF,零标志位
                                                                                                                                                          • PF,奇偶标志位
                                                                                                                                                            • SF,符号标志位
                                                                                                                                                              • CF,进位标志位
                                                                                                                                                                • OF,溢出标志位
                                                                                                                                                                  • adc指令
                                                                                                                                                                    • sbb指令
                                                                                                                                                                      • cmp指令
                                                                                                                                                                        • 检测比较结果的条件转移指令
                                                                                                                                                                          • DF标志和串传送指令
                                                                                                                                                                            • pushf和popf
                                                                                                                                                                            • 第十二章,内中断
                                                                                                                                                                              • 内中断的产生
                                                                                                                                                                                • 中断处理程序
                                                                                                                                                                                  • 中断向量表
                                                                                                                                                                                    • 中断过程
                                                                                                                                                                                      • 中断处理程序
                                                                                                                                                                                        • 除法错误中断处理
                                                                                                                                                                                          • 编程处理0号中断
                                                                                                                                                                                            • 单步中断
                                                                                                                                                                                              • 响应中断的特殊情况
                                                                                                                                                                                              • 第十三章,int指令
                                                                                                                                                                                                • int指令
                                                                                                                                                                                                  • 对int,iret与栈的深入理解
                                                                                                                                                                                                    • BIOS与dos中断例程的安装
                                                                                                                                                                                                      • BIOS中断历程应用
                                                                                                                                                                                                      • 第十四章,端口
                                                                                                                                                                                                        • 端口的读写
                                                                                                                                                                                                          • CMOS RAM 芯片
                                                                                                                                                                                                            • shl与shr指令
                                                                                                                                                                                                              • CMOS RAM中存储时间信息
                                                                                                                                                                                                              • 第十五章,外中断
                                                                                                                                                                                                                • 接口芯片和端口
                                                                                                                                                                                                                  • 外中断信息
                                                                                                                                                                                                                    • PC键盘的处理过程
                                                                                                                                                                                                                      • 编写int 9 中断例程
                                                                                                                                                                                                                        • 安装新的int 9终端例程
                                                                                                                                                                                                                        • 第十六章,直接定址表
                                                                                                                                                                                                                          • 描述了单元长度的标号
                                                                                                                                                                                                                            • 在其他段中使用数据标号
                                                                                                                                                                                                                              • 直接定址表
                                                                                                                                                                                                                                • 程序入口地址的直接定址表
                                                                                                                                                                                                                                • 第十七章,BIOS键盘的输入磁盘读写
                                                                                                                                                                                                                                  • int 9 中断对键盘输入的处理
                                                                                                                                                                                                                                    • int 16 读取键盘缓冲区
                                                                                                                                                                                                                                      • 字符串的输入
                                                                                                                                                                                                                                        • int 13h
                                                                                                                                                                                                                                        领券
                                                                                                                                                                                                                                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档