汇编语言 知识点梳理(王爽)
汇编语言(王爽)
第一章 基础知识
汇编语言的三类指令
(1)汇编指令:机器码的助记符,有对应的机器码
(2)伪指令:没有对应的机器码,由编译器执行,计算机不执行
(3)其它符号,如+,-,*,/等,由编译器识别,没有对应的机器码
指令和数据
在内存或磁盘上,指令和数据没有区别,都是二进制信息
总线
地址总线:一个CPU有N根地址总线,可以说、CPU的地址总线宽度是N,最多可以寻找2的N次方个内存单元
数据总线:宽度决定cpu与外界数据传送速度
控制总线:宽度决定cpu对外部器件的控制能力
第二章 寄存器
CPU的组成
控制器:控制各种器间进行工作
运算器:信息处理
寄存器:进行信息存储
内部总线:连接各种器件,在它们之间进行数据传送
通用寄存器
AX,BX,CX,DX存放一般性的数据,8086cpu寄存器都是16位的,可以存放两个字节(1个字)
AX可以分为AH,AL
8086给出物理地址的方法
(1)在内部用两个16位地址合成的方法形成20位的物理地址
一个称为段地址,一个称为偏移地址
(2)段地址和偏移地址通过内部总线送入地址加法器
(3)地址加法器将两个16位地址合成一个20位的物理地址
物理地址 = 段地址x16+偏移地址
地址加法器将二进制地址左移4位,完成段地址x16
(4)地址加法器通过内部总线将20位物理地址送入 输入输出控制电路
(5)输入输出控制电路将20位物理地址送上地址总线
(6)20位物理地址被地址总线送到存储器
补充:一个x进制的数据左移1位,相当于乘以x
段地址
一个段的起始地址一定是16的倍数,偏移地址16位,代表寻址能力为64KB,故一个段最大长度为64kb
可以用不同的段地址和偏移地址形成同一个物理地址
可以根据需要,将地址连续,起始地址为16的倍数的一组内存单元定义为一个段
CS IP
cs为代码段寄存器,IP为指令指针寄存器
CPU将cs ip指向的内存单元中的内容看作指令,如果说内存中一段信息曾被CPU执行过,
那么,它所在的内存单元必然被cs ip指向过
修改cs ip的指令
mov:传送指令
jump: 用寄存器中的值修改ip
第三章 寄存器(内部访问)
小端模式
高地址内存单元中存放数据高位,低地址存放数据低位
用0,1两个内存单元存放数据4E20H
将起始地址为N的字单元称为N地址字单元,如0地址字单元存放4E20H
1地址字单元存放124EH
段地址和[address]
DS用来存放要访问数据的段地址
mov bx, 1000Hmov ds, bxmov al, [0]
以上三条指令将10000H(1000:0)中的数据读到al中
[]表示一个内存单元,0表示内存单元的偏移地址,mov ds,1000H是非法的
需要有一个寄存器进行中转
mov bx,1000Hmov ds,bxmov[0], al
将al中的数据送入内存单元10000H中
mov ax,123BHmov ds, axmov al, 0add al,[0]add al,[1]add al,[2]
累加数据段的前三个单元中的数据
栈
段寄存器SS、寄存器SP存放栈顶位置
push ax指令
sp=sp-2,将ax中内容(2266H)送入ss:sp 指向的内存单元处
栈空时,sp指向栈空间最高地址的下一个单元
pop ax后
pop执行后,2266H任然存在,但是已经不在栈中
push 寄存器 ;将一个寄存器中的数据入栈
pop 寄存器 ;出栈,用一个寄存器接收出栈的数据
在10000H处写入字型数据2266H,不允许 mov 内存单元,寄存器的指令
mov ax, 1000Hmov ss, axmov sp, 2mov ax, 2266Hpush ax
第一个汇编程序
;ex1.asm
assume cs:code
code segmentdw 0241h,0242h,0243h,0244h,0245h
start:mov ax, 0b800hmov ds, axmov bx, 0mov cx, 5
s: mov ax,cs:[bx]mov [bx], axadd bx ,2loop smov ah, 4chint 21h
code ends
end start
masm ex1;–>编译源程序
link ex1;–>链接
ex1 -->执行
执行结果
第五章 [bx]和loop指令
[bx]
mov ax, [bx]
将一个内存单元内容送入ax,内存单元长度为2字节,
偏移地址在bx中,段地址在ds中,相当于 (ax)=((ds)*16+(bx))
mov al, [bx]与之类似
mov [bx], ax
将bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将ax中数据送入内存SA:EA处
((ds)*16+(bx))=(ax)
inc
inc bx含义是bx中的内容加1
mov bx, 1inc bx
执行后bx=2
()
()用于表示一个寄存器或者一个内存单元里的内容
(ax)表示ax中的内容
(20000H)表示内存20000H单元的内容,()中的内存单元地址为物理地址
((ds)*16+(bx))表示:ds中的地址作为段地址add1,bx中的地址为偏移地址add2,
内存add1:add2单元的内容
()中元素可以有三种类型:
- 寄存器名
- 段寄存器名
- 内存单元的物理地址(20位)
idata
用idata表示常量
mov ax, [idata] ;代表mov ax, [1] mov ax, [2]等mov ax, idata ;代表mov bx, 1 mov bx, 2 等
但是,在汇编源程序中,想在[]里用idata给出内存单元的偏移地址,就要在[]前面显示
给出段地址所在的段寄存器,否则编译器masm将[idata]视为idata
mov al, ds:[0]mov al, [0] ;等效与mov al, 0
loop指令
loop指令格式是 :loop 标号,CPU执行loop指令时,需要两步操作
- (cx)=(cx)-1
- 判断cx值是否为0,不为0则转至标号处执行,为0则顺序执行
注意:
标号代表一个地址,标号所标识的地址要在前面
cx中保存循环的次数
example
assume cs:code
code segmentmov ax, 2mov cx, 11
s: add ax, axloop smov ax, 4c00hint 21h
code ends
end
段前缀
用于显式指明内存单元的段地址的 ds: cs: ss: es: 在汇编语言中称为段前缀
mov ax, ds:[bx]mov ax, cs:[bx]mov ax, ss:[bx]mov ax, es:[bx]mov ax, ss:[0]mov ax, cs:[0]
结合idata理解
;exampleassume cs:codecode segmentmov ax, 0ffffhmov ds, ax ;(ds)=0ffffhmov ax, 0020hmov es, ax ;(es)=0020hmov bx, 0 ;(bx)=0, 此时ds:bx指向ffff:0,es:bx指向0020:0mov cx, 12 ;(cx)=12,循环12次s:mov dl, [bx]mov es:[bx], dlinc bxloop smov ax, 4c00hint 21h
code ends
end
第六章 包含多个段的程序
程序取得空间的方法有两种
- 在加载程序时候为程序分配
- 在执行过程中向系统申请
重点讨论第一种
将数据,代码,栈放入不同的段
原因:
- 将数据,栈,代码放入一个段使程序混乱
- 数据,栈,代码需要的空间可能超过64KB
;example
assume cs:code, ds:data, ss:stackdata segmentdw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987hdata endsstack segmentdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0stack endscode segmentstart: mov ax, stackmov ss, axmov sp, 20h ;设置栈顶ss:sp指向stack:20mov ax, datamov ds, ax ;ds指向data段mov bx, 0 ;ds:bx指向data段的第一个单元mov cx, 8s:push [bx]add bx, 2loop s ;将data段0-15单元中8个字型数据依次入栈mov bx, 0mov cx, 8
s0:pop [bx]add bx, 2loop s0 ;依次出栈8个字型数据到data段的0-15单元中mov ax, 4c00hint 21hcode ends
end
(1)定义多个段的方法:对于不同的段,要有不同的段名
(2)对段地址的引用:
在程序中,段名相当于一个标号,代表了段地址
mov ax, data 含义是将名称为data段的段地址送入ax
(3)代码段,数据段,栈段等的命名,是程序员的安排
CPU并不清楚各个段名的意义,data, stack, code 段名只是使程序便于阅读
第七章 更灵活的定位内存地址的方法
and与or指令
通过or指令可以将操作对象的相应位设为0,其它位不变
mov al, 01100011B;将al第6位设为0:and al, 10111111B;将al第7位设为0:and al, 01111111B;将al第0位设为0:and al, 11111110B
通过or指令可以将操作对象相应位设为1
mov al, 01100011B;将al第6位设为1:or al, 01000000B;将al第7位设为1:or al, 10000000B;将al第0位设为1:or al, 00000001B
以字符形式给出的数据
data segmentdb 'unix'db 'foRK'
data ends
上面的源程序中
db ‘unix’ 相当于 db 75H, 6EH, 49H, 58H
db ‘foRK’ 相当于 db 66H, 6FH, 52H, 4BH
mov al, ‘a’ 相当于mov al, 61H,a的ASCII码为61H
大小写转换问题
大写 十六进制 二进制 小写 十六进制 二进制
A 41 01000001 a 61 01100001
B 42 01000010 b 62 01100010
观察发现,小写字母的Ascii码比大写字母的ASCII码值大20H
不能通过加减20H的方法改变大小写,因为这种方法需要判断字符是大写还是小写
观察大小写字母的二进制形式,只有第五位不同,
大写字母第五位为0,小写字母第五位为1,可以用and和or实现
and al, 11011111B ;将第五位置为0,小写字母->大写字母
or al, 00100000B ;将第五位置为1,大写字母->小写字母
assume cs:codesg, ds:datasg
datasg segmentdb 'BaSiC'db 'iNfOrMaTion'
datasg endscodesg segment
start:mov ax, datasg mov ds, ax ;设置ds指向datasg段mov bx, 0 ;设置(bx)=0,ds:bx指向'BaSiC'的第一个字母mov cx, 5 ;设置循环次数5,因为'BaSiC'有五个字母
s:mov al, [bx] ;将ASCII码从ds:bx所指的单元取出and al, 11011111B ;将al中ASCII码的第五位置位0,变为大写字母mov [bx], al ;将转变后的ASCII码写回原单元inc bxloop smov bx, 5 ;设置(bx)=5,ds:bx指向'iNforMaTion'的第一个字母mov cx, 11 ;'iNforMaTion有11个字母,需要循环11次's0:mov al, [bx]or al, 00100000B ;将al中ASCII码第五位置位1,变为小写字母Mov [bx], alinc bxloop s0mov ax, 4c00Hint 21h
codesg ends
end start
[bx+idata]
[bx+idata]表示一个内存单元,它的偏移地址是(bx)+idata (bx中的数值加上idata)
mov ax, [bx+200]含义:将一个内存单元中的内容送入ax,这个内存单元的长度为2个字节,
存放一个字,偏移地址为bx中的数值加上200,段地址在ds中
即:(ax)=((ds)*16+(bx)+200)
该指令也可以写成 mov ax, [200+bx] mov ax, 200[bx] mov ax, [bx].200
[bx+idata]的应用:进行数组的处理
;example
通过比较发现,[bx+idata]的方式为高级语言实现数组提供了便利机制
SI和DI
si和di是8086CPU中和bx功能相近的寄存器,si和di不能分成两个8位寄存器使用
mov bx, 0
mov ax, [bx]
mov si, 0
mov ax, [si]
mov di, 0
mov ax, [di]
以上三组指令实现的功能相同
;用si和di将字符串'welcome to masm'复制到他后面的区域
assume cs:code, ds:datadata segmentdb 'welcome to masm!'db '............... '
data endscode segment
startmov ax, datamov si, 0mov di, 16mov cx, 8s:mov ax, [si]mov [di], axadd si, 2add di, 2loop smov ax, 4c00hint 21h
code ends
end start;使用[bx+idata]方式优化
code segment
start:mov ax, datamov ds, axmov si, 0mov cx, 8s:mov ax, 0[si]mov 16[si], axadd si, 2loop smov ax, 4c00hint 21h
code ends
end start
[bx+si]和[bx+di]
mov ax, [bx+si]含义如下:
将一个内存单元中的内容送入ax, 这个内存单元偏移地址位bx中的数值加上si中的数值
段地址在ds中
数学表示:(ax)=((ds)*16+(bx)+(si))
也可以写成 mov ax, [bx] [si]
[bx+si+idata]和[bx+di+idata]
mov ax, [bx+si+idata]含义:将一个内存单元的内容送入ax,
偏移地址为(bx)+(si)+idata,段地址在ds中
数学表示:(ax) = ((ds*16)+(bx)+(si)+idata)
也可以写成 mov ax, [bx+200+si]
mov ax, [200+bx+si]
mov ax, 200[bx] [si]
mov ax, [bx].200[si]
mov ax, [bx] [si].200
不同寻址方式的灵活应用
- [idata]用一个常量表示地址,可以用于直接定位一个内存单元
- [bx]用一个变量表示内存地址,可以用于间接定位一个内存单元
- [bx+idata]用一个变量和常量表示地址,可以在一个起始地址的基础上用变量间接定位一个内存单元
- [bx+si]用两个变量表示地址
- [bx+si+idata]用两个变量和一个常量表示地址
;
第八章 数据处理的两个基本问题
基本问题
- 处理的数据在什么地方
- 要处理的数据有多长
定义描述性符号reg和sreg表示寄存器和段寄存器
reg:ax, bx, cx, dx, ah, al, bh, bl, ch, cl, dh, dl, sp, bp, si, di
sreg: ds, ss, cs, es
bx,si, di和bp
(1)8086cpu中,只有这4个寄存器可以用在[]中进行内存单元的寻址
mov ax, [bx]mov ax, [bx+si]mov ax, [bx+di]mov ax, [bp]mov ax, [bp+si]mov ax, [bp+di]
(2)在[]中,这4个寄存器只能单个出现或者以4中组合出现
mov ax, [bx+si]mov ax, [bx+di]mov ax, [bp+si]mov ax, [bp+di]mov ax, [bx+si+idata]mov ax, [bx+di+idata]mov ax, [bp+si+idata]mov ax, [bp+di+idata]
如mov ax, [bx+bp] mov ax, [si+di]是错误的
(3)[bp]的默认段地址在ss中
mov ax, [bp+si+idata] ;含义:(ax)=((ss)*16+(bp)+(si)+idata)
机器指令处理的数据在什么地方
指令执行前,所要处理的数据可以放在三个地方
- CPU内部
- 内存
- 端口
数据位置的表达
(1)立即数idata执行前放在CPU指令缓存器中
mov ax, 1
add bx, 2000h
(2)寄存器,指令要处理的数据在寄存器中
mov ax, bxmov ds, axpush bxmov ds:[0], bxpush dsmov ss,axmov sp, ax
(3)段地址(SA)和偏移地址(EA)
段地址寄存器可以是默认的
;默认在ds中
mov ax, [0]
mov ax, [di]
mov ax, [bx+8]
mov ax, [bx+si]
mov ax, [bx+si+8];默认在ss中
mov ax, [bp]
mov ax, [bp+8]
mov ax, [bp+si]
mov ax, [bp+si+8]
也可以显性给出
mov ax, ds:[bp]
mov ax, es:[bx]
mov ax, ss:[bx+si]
mov ax, cs:[bx+si+8]
寻址方式
指令要处理的数据有多长
(1)通过寄存器名指明要处理数据的尺寸
;字操作
mov ax, 1mov bx, ds:[0]mov ds, axmov ds:[0], axinc axadd ax, 1000;字节操作
mov al, 1
mov al, bl
----
(2)用x ptr指明内存单元的长度,x可以为word或者byte
mov word ptr ds:[0], 1
mov byte ptr ds:[0], 1
寻址方式的综合应用
div指令
(1)除数:有8位和16位两种,在一个reg或内存单元中
(2)被除数:默认放在AX或者 DX和AX中,如果除数为8位,被除数则位16位,默认在AX中存放
如果除数为16位,被除数则为32位,在DX和AX中存放,DX存高16位,AX存低16位
(3)结果:如果除数为8位,则AL存储除法操作的商,AH存储余数,(AH是AX的高位)
如果除数为16位,AX存放商,DX存储余数
div byte ptr ds:[0]
含义:(al)=(ax)/((ds)*16+0)的商(ah)=(ax)/((ds)*16+0)的余数div word ptr es:[0]
含义:(ax)=[(dx)*10000H+(ax)]/((es)*16+0)的商(dx)=[(dx)*10000H+(ax)]/((es)*16+0)的余数
伪指令dd
db:定义字节型数据 define byte
dw:定义字型数据 define word
dd:定义双字型数据 define dword
dup
dup是一个操作符,如同db,dw,dd等一样,是由编译器识别处理的,用来进行数据的重复
db 3 dup(0)
;定义了3个字节,它们的值都是0,相当于定义了db 0,0,0db 2 dup(0,1,2)
;定义了9个字节,相当于db 0,1,2,0,1,2,0,1,2
实验1
用汇编指令编码和调试
实验任务2
给出使用d命令查看生产时期的截图给出使用e命令修改生产日期所在内存单元的截图,以及,修改后,再次使用d命令查看的截图结论:能否修改,以及,原因分析
时间并未被修改,因为生产日期在C0000~FFFFF地址范围内,在其中写入数据是无效的,相当于只改写只读存储器中的内容
实验任务3
给出在debug中使用e命令修改内存单元的命令,及,效果截图给出在debug中使用f命令批量填充内存单元的命令,及,效果截图尝试修改内存单元,或,数据后的效果截图
实验任务4
根据在debug环境中调试观察结果,填空并回答问题。填空注*: 以下这段汇编指令代码,是在debug环境中使用a命令输入的汇编指令。debug环境中,默认十六进制。回答问题
[](javascript:void(0)
汇编语言 知识点梳理(王爽)相关推荐
- 汇编语言答案(王爽)第三版
汇编语言答案王爽第三版 检测点11 检测点21 检测点22 检测点23 检测点31 检测点32 检测点32 检测点61 检测点61 检测点91 检测点91 检测点92 检测点93 检测点101 检测点 ...
- 【汇编语言】by王爽 | 实验10:编写子程序
前言:本实验为王爽老师的<汇编语言>第三版中的实验10(p206) 实验环境:DOSBox 0.74-3 实验任务: 1.显示字符串 问题 显示字符串是现实工作中经常要用到 ...
- 【汇编语言】(王爽)实验4解答
题目1 编程:向内存0:200 - 0:23F 中存放数据 0 - 3FH ; 向内存 0:200 ~ 0:23f 写入数据0~3fH[字节型数据] assume cs:code code segme ...
- 汇编语言笔记(王爽)
目录 @[TOC](目录) 通用寄存器 CS和IP 修改CS.IP的指令 小 结 内存中的字的存储 小结 SI和DI [bx+si]和[bx+di] [bx+si+idata]和[bx+di+idat ...
- 汇编语言(王爽第三版) 实验5编写、调试具体多个段的程序
参考:http://blog.sina.com.cn/s/blog_171daf8e00102xclx.html 汇编语言实验答案 (王爽):https://wenku.baidu.com/view/ ...
- 汇编语言答案-王爽第三版
汇编语言答案(王爽) 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位. (2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023 . (3) ...
- 王爽汇编语言第三版答案
转载自 https://blog.csdn.net/modiz/article/details/88776695 部分加上自己的分析,感谢 Modiz 汇编语言答案(王爽) 检测点1.1 (1)1个C ...
- 汇编语言王爽第三版答案
汇编语言答案(王爽) 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位. (2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023 . (3) ...
- 【汇编语言】8086、x86-32和C语言【赋值语句 和 数组】的对比学习(王爽学习笔记:5.8段前缀的使用)
0 前言 这里给出两种思路,都比王爽老师书上的做法要简单高效,事实上,理解指令的本质,就能达到灵活应用,这样才能打破规则 题目:将内存ffff:0 - ffff:b的数据,复制到内存ffff:10 - ...
最新文章
- 《3ds Max疯狂设计学院》——1.8节本章小结
- 76.Zabbix添加图形和聚合图形
- 从入门到实践:创作一个自己的 Helm Chart
- mysql的extract_mysql中json_extract函数的使用?作用是什么?
- 使用putty连接linux
- python是用来初始化_python的初始化运行了哪些?
- SecureCRT日志配置
- 在Spring中使用JDBC访问关系数据
- mysql存储过程中删除定时器_mysql创建存储过程,定时任务,定时删除log 莫大人...
- Java千百问_05面向对象(004)_java接口到底是什么
- ECS弹性网卡+弹性公网IP配置最佳实践之策略路由
- mongodb 插入一个数组 java_mongodb:推送到数组元素的子数组或添加到数组(如果不存在)...
- python支持向量机 股票_测 python 利用SVM预测股票涨跌
- 唐僧为什么可以领导孙悟空(项目管理)
- 传奇人物李兴平5000万卖掉hao123后在做什么
- latex显示错误:Text line contains an invalid character. l.1
- 算法工程师面试之集束算法(beam search)
- 纯CSS3实现旋转风车
- RationalDMIS 7.1 建立坐标系(3-2-1法)
- Ubuntu折腾--优化wine 微信小黑框处理
热门文章
- Logback第十四章:Receivers
- SpringBoot——配置文件里的全局变量
- 华中科技大学计算机acm,我校代表队在2018年ACM-ICPC世界总决赛中取得佳绩
- 使用Platium库开发dlna投屏功能
- HUAWEI DevEco Testing注入攻击测试:以攻为守,守护OpenHarmony终端安全
- c语言实现农夫过河问题,傻瓜式讲解,看不明白来打我
- npm install @antv/xflow无法下载该依赖
- 华南师范大学计算机学院重修,华南师范大学计算机学院、软件学院本科生学年评优工作条例...
- UWB定位基站铺设原则简析
- 算法分析与设计期末总结(安徽大学)