汇编
目的:充分获得底层编程的体验,深可理解机械运行程序的机理。(使用8086CPU)
1.1机器语言
概念:机械指令的集合。(一串二进制,并由计算机转变成高低电平)
1.2汇编的产生
主体:汇编指令(其是机械指令便于记忆的书写格式)
寄存器:CPU中可以存储数据的器件,一个CPU有多个寄存器。
编译器:将汇编指令转成机械指令的翻译程序。
1.4存储器
1)为CPU提供指令和数据(就是我们常说的内存)。
1.5指令和数据
指令和数据都是应用上的概念,在内存和硬盘上并无任何区别。
1.6存储单元
存储器被划分为若干个存储单元(它们都是从0开始)。
计算机最小信息单位是bit。
1.7CPU对存储器的读写
1)CPU对数据的读写需要地址信息(地址总线),控制信息(控制总线),数据信息(数据总线)的交互。(发送电信号通过导线(总线)传送。)
1.8地址总线(CPU通过地址总线来指定存储器单元)
一个CPU有N根地址线,则可以说其宽度为N,最多能找2的N次方个内存单元。
1.9数据总线
数据总线的宽度决定了CPU与外界的数据传送速度。
1.10控制总线
1)控制总线是一些不同控制线的集合。
2)有多少控制总线就有多少种控制。(控制总线的宽度决定了CPU对外界的控制能力)
检测点1.1
1)13
2)1024 0 1023
3)8192(1024*8) 1024
4)1024*1024*1024 1024*1024 1024
5)64 1 16 4
6)1 1 2 2 4
7)512 256
8)二进制
1.11内存地址空间
寄存器
对于汇编程序员来说,CPU中主要的部件是寄存器。寄存器是CPU中程序员可以用指令读写的部件。
不同的CPU,寄存器的个数和结构都不相同。
8086CPU(14个寄存器):AX,BX, CX, DX, SI, DI, SP, BP, IP, CS, SS, DS, ES, PSW
2.1通用寄存器
1)AX, BX, CX, DX 都是通常用来存放一般性的数据(即通用寄存器)。
2)这些寄存器可分为高位和低位:
如
2.3开始汇编指令
/add时注意溢出则舍去/
检测点2.1:
1)F4A3H 31A3H 3123H 6246H 826CH 6246H 826CH 04D8H 0482H 6C82H D882H D888H D810 6246H
mov ax 0002H
add ax ax
add ax ax
add ax ax
2.4物理地址
物理地址:每一个内存单元中的唯一地址。
2.5 16位结构的CPU
其结构特征:
8086要读写内存时:
地址加法器采用的方法:物理地址=段地址*16+偏移地址
“段地址*16+偏移地址=物理地址”的本质含义是:CPU在访问内存时,用一个基础地址(段地址*16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。(基础地址+偏移地址=物理地址)
2.8段的概念
1)CPU可以通过不同的段地址和偏移地址形成同一个物理地址。
2)仅用偏移地址寻找地址可以找到64KB个内存单元。
检测点2.2:
0010H 1000FH
10001H 20000H
2.9段寄存器
1)8086CPU有四个段寄存器:CS, DS, SS, ES
2.10CS和IP
CS和IP是8086CPU中最关键的寄存器。
CS:代码段寄存器 IP:指令指针寄存器
8086CPU的工作过程:
2.11 修改CS,IP的指令
1)8086CPU大部分的寄存器的值都可以通过mov改变,mov被称为传送指令。
但mov指令不能用于设置CS,IP的值。
2)能够改变CS,IP的指令叫转移指令。
3)最简单的转移指令是jmp指令。
用法:jmp段地址:偏移地址
功能:用指令给出的段地址修改CS,偏移地址修改IP.
特殊:仅修改IP可用“jmp 某一个合法寄存器”。(用寄存器中的值修改IP)
2.12代码段
如果要执行一个代码段内的代码,必须将指针指向代码段的开头。
检测点2.3:
4次,每一次指令还有一个执行“jmp ax” IP=0000h
实验一 查看CPU和内存,用机器指令和汇编指令编程
1)预备知识:Debug的使用
what:DOS、windows都提供的实模式程序的调试工具。
寄存器(内存访问)
3.1内存中字的存储
1)一个单元存放一个字节
字单元:存放字型数据(16位)的内存单元。
2)任何两个地址连续的内存单元的地址,N号单元和N+1号单元,可以把它们看成两个内存单元。
3.2DS和【address】
1)mov可以完成三种传送:first、将数据直接送入寄存器;second、将一个内存单元中的内容送入另一个寄存器;third、将一个内存单元的内容送入一个寄存器·。
2)执行指令时,8086CPU会自动取ds中的内存单元的段地址。
3)mov ds,1000h(是非法指令)。
3.4mov、add、sub指令
1)、mov 寄存器 数据 mov ax,8
2)、mov 寄存器 寄存器 mov ax,bx
3)、mov 内存单元 寄存器 mov [0],ax
4)、mov 寄存器 内存单元 mov ax,[0]
5)、mov 段寄存器,寄存器 mov ds,ax
3.5数据段
检测3.1
1)、2662 e626 e626 2662 d6e6 fd48 2c14 0000 00e6 0000 0026 000c
2)、jmp 2000:0000 mov ax 1000h mov ds ax mov ax 0 mov bx 0
3.6栈
只有入栈(PUSH)和出栈(POP)两个基本操作。
操作规则:LIFO
3.7CPU提供的栈机制
3.9push、pop指令
push和pop都是可以在寄存器和内存之间传送数据。
push(pop) 寄存器
push(pop) 段寄存器
push(pop) 内存单元
栈操作机制:
执行push指令时,是先改变sp,在进行传送
执行pop指令时,是先传送,在进行改变sp
栈顶的变化范围最大为:0~ffffh
检测点3.2
1)、mov ax, 2000H
mov ss,ax
mov sp,10h
2)、mov ax,1000h
mov ss,ax
mov sp,0
第一个程序
4.2源程序
assume cs:codesg
codesg segment
mov ax,0123h
mov bx,0456h
add ax,bx
add ax,ax
mov ax,4c00h
int 21h
codesg ends
end
1)、程序包括伪指令(由编译器所执行)和汇编指令(有对应的机械码指令,被CPU所执行)。
segment(段的开始)和ends(段的结束)是一对成对使用的伪指令(用于定义一个段)。
end是一个汇编程序的结束标记。
assume(含意为假设)。
程序返回:
实现的指令:
mov ax,4c00h
int 21h
【bx】和loop指令
1)、要描述一个内存单元,需要内存单元的地址和内存单元的长度(类型)。
2)、loop==循环。
3)进行loop时,需要两个操作:
(cx)=(cx)-1
判断cx中的值是否为0
assume cs:code
code segment
mov ax,2
mov cx,11
s:add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
在cx中存放循环次数;
loop指令中的标号所标识地址要在前面