《汇编语言》(王爽)第8章 数据处理的两个基本问题--笔记
- 格式:pdf
- 大小:178.73 KB
- 文档页数:2
汇编语言》-王爽-完美高清版-零基础汇编语言入门书籍PDF格式同时按ctrl+要下载的地址既可下载对应的视频下载地址:/file/f61cb107c8001第一章- 基础知识01下载地址:/file/f6806f45b8002第一章- 基础知识02下载地址:/file/f6ec42d4d3003第一章- 基础知识03下载地址:/file/f6deb05ec4004第一章-基础知识04下载地址:/file/f6e51f6838005第一章- 基础知识05下载地址:/file/f66edaf8d3006第二章- 寄存器(CPU工作原理)01下载地址:/file/f6d07e07b9007第二章- 寄存器(CPU工作原理)02下载地址:/file/f6d7f585a8008第二章- 寄存器(CPU工作原理)03下载地址:/file/f639d8b3cf009第二章- 寄存器(CPU工作原理)04下载地址:/file/f6dcadbde6010第二章- 寄存器(CPU工作原理)05下载地址:/file/f6ea3f01c1011第二章- 寄存器(CPU工作原理)06下载地址:/file/f65b96a06f012第二章- 寄存器(CPU工作原理)07下载地址:/file/f682da085a013第三章- 寄存器(内存访问)01下载地址:/file/f6486e698014第三章- 寄存器(内存访问)02下载地址:/file/f6b7491d9f015第三章- 寄存器(内存访问)03下载地址:/file/f622b7f9a7016第三章- 寄存器(内存访问)04下载地址:/file/f64e2424b9017第三章- 寄存器(内存访问)05下载地址:/file/f6e5132d4d018第三章- 寄存器(内存访问)06下载地址:/file/f655c10e86019第三章- 寄存器(内存访问)07下载地址:/file/f6b22e64e6020第四章- 第一个程序01下载地址:/file/f6812126a4021第四章- 第一个程序02下载地址:/file/f6523e625c022第四章- 第一个程序03下载地址:/file/f63e0ccb28023第五章- [BX]和loop指令01下载地址:/file/f611e07b8a#024第五章- [BX]和loop指令02下载地址:/file/f6e047bccc#025第五章- [BX]和loop指令03下载地址:/file/f6d348d781#026第五章- [BX]和loop指令04下载地址:/file/f6ada24153#027第五章- [BX]和loop指令05下载地址:/file/f64f97518b#028第五章- [BX]和loop指令06下载地址:/file/f6f9ba96f8#029第六章- 包含多个段的程序01下载地址:/file/f650e06f38#030第六章- 包含多个段的程序02下载地址:/file/f683ee5b2a#031第六章- 包含多个段的程序03下载地址:/file/f69009bfc2#032第七章- 更灵活定位内存地址的方法01下载地址:/file/f6ea427646#033第七章- 更灵活定位内存地址的方法02下载地址:/file/f6acdc6b7f#034第七章- 更灵活定位内存地址的方法03下载地址:/file/f6c85745d0#035第七章- 更灵活定位内存地址的方法04下载地址:/file/f61a26cf12#36第七章- 更灵活定位内存地址的方法05下载地址:/file/f631edf5c6#037第七章- 更灵活定位内存地址的方法06下载地址:/file/f6b0fa6fb8#038第八章- 数据处理的两个基本问题01下载地址:/file/f6f5fe8962#039第八章- 数据处理的两个基本问题02下载地址:/file/f6bf975e0#040第八章- 数据处理的两个基本问题03下载地址:/file/f6d522784c#041第八章- 数据处理的两个基本问题04下载地址:/file/f6b5ac9991# 042实验七寻址方式在结构化数据访问中的应用下载地址:/file/f62e80ced5#076第十七章_使用BIOS进行键盘输入和磁盘读写02/file/bhbgrnfz#077第十七章_使用BIOS进行键盘输入和磁盘读写03[url=/file/dnsl0kxp#[/sell]/file/dnsl0kxp#[/sell[/url]]。
王爽《汇编语⾔》实验8
实验8是要求阅读⼀个很奇葩的代码:
assume cs:code
code segment
mov ax, 4c00h
int 21h
start: mov ax, 0
s: nop
nop
;下⾯这段代码主要是把s2的内容复制到s处
mov di, offset s
mov si, offset s2
mov ax, cs:[si]
mov cs:[di], ax
s0: jmp short s
s1: mov ax, 0
int 21h
mov ax, 0
s2: jmp short s1
nop
code ends
end start
先看看开始时代码在内存的存在:
对⽐前⾯的代码,可以看出,程序从start处开始运⾏,然后⼀直运⾏到mov cs:[di], ax处,
此时再查看内存:
发现标签s处的代码已经被更改成为jmp 0000,但是s2处的明明是jmp short s1啊,为什么把代码复制到s处就不同了?
再仔细观察,发现这个指令的机器码EBF6并没有改变,⽽因为jmp short是段内转移,机器码记录的是位移,F6对应的是-8的位移,⽽由于s 刚好处于cs:0008处,运⾏jmp后刚好后移8位,到达最开始的mov ax, 4c00h处,到此运⾏结束。
这⾥对于这个-8的位移控制得⾮常精妙,从s2转移到s1需要-8的位移,⽽从s转移到段头处也刚好是-8的位移,所以程序运⾏成功。
从这⾥可以看出,⼀个精妙的汇编代码⽐⾼级语⾔更有意思^_^。
汇编语言学习笔记《汇编语言》--王爽前言学习汇编目的:充分获得底层编程体验;深刻理解机器运行程序的机理。
原则:没有通过监测点不要向下学习;没有完成当前实验不要向下学习。
第一章基础知识有三类指令组成汇编语言:汇编指令;伪指令;其他符号。
8bit = 1byte = 一个存储单元有n根地址线,则可以寻址2的n次方个内存单元。
1.1节--1.10节小结(1)汇编指令是机器指令的助记符,同机器指令一一对应。
(2)每一种cpu都有自己的汇编指令集。
(3)cpu可以直接使用的信息在存储器中存放。
(4)在存储器中指令和数据没有任何区别,都是二进制信息。
(5)存储单元从零开始顺序编号。
(6)一个存储单元可以存储8个bit,即八位二进制数。
(7)每一个cpu芯片都有许多管脚,这些管脚和总线相连。
也可以说,这些管脚引出总线。
一个cpu可以引出的三种总线的宽度标志了这个cpu不同方面的性能。
地址总线的宽度决定了cpu的寻址能力;数据总线的宽度决定了cpu与其他器件进行数据传送时的一次数据传送量;控制总线的宽度决定了cpu对系统中其他器件的控制能力。
监测点:1KB的存储器有1024个存储单元?存储单元的编号从0到1023.内存地址空间:最终运行程序的是cpu,我们用汇编编程时,必须要从cpu的角度思考问题。
对cpu来讲,系统中的所有存储器中的存储单元都处于一个统一的逻辑存储器中,它的容量受cpu寻址能力的限制。
这个逻辑存储器即是我们所说的内存地址空间。
第二章寄存器(cpu的工作原理)mov ax, 2add ax, axadd ax, axadd ax, ax(1)cpu中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址;(2)段地址和偏移地址通过内部总线送人一个称为地址加法器的部件;(3)地址加法器将两个16位地址合成为一个20位的物理地址;(4)地址加法器通过内部总线将20位物理地址送人输入输出控制电路;(5)输入输出控制电路将20位物理地址送上地址总线;(6)20位物理地址被地址总线传送到存储器;段地址*16+偏移地址= 物理地址的本质含义内存并没有分段,段的划分来自cpu。
学_汇编语⾔_王爽版要点采集笔记(未完待续...)第⼀章基础知识存储器(内存)存放CPU⼯作的指令和数据(CPU可以直接使⽤的信息在内存中存放);指令和数据都是⼆进制数没有任何区别,由CPU决定是数据还是指令内存单元:存储器被分为若⼲个存储单元,并从0开始编号(存储单元的地址),⼀个存储单元为1字节(8bit)CPU的读写总线逻辑上分为:地址总线、数据总线、控制总线地址总线:地址线宽度决定了CPU的寻址能⼒,计算⽅式:2^[地址线宽](个内存单元)数据总线:决定了CPU和外界的数据传输速度(8根数据总线可传送⼀个8位(bit)⼆进制数,即1个字节)控制总线:是各外部器件的不同控制线的集合CPU进⾏数据读写必须经过3类信息交互:①存储单元的地址(地址信息)②器件的选择,读或写的命令(控制信息)③读或写的数据(数据信息)读:CPU在内存中读取数据时,要先指定存储单元的地址(你要找⼀个地⽅先要确定⼀个地址),会把要读取的地址经过地址总线发给内存;同时CPU控制器将内存读命令通过控制总线发送给内存,并通知内存要读取数据;最后内存将被指定的内存单元中的数据经过数据总线送⼊CPU写:与读类似,CPU经地址线发送要操作的内存单元的地址,CPU经控制线将内存写命令发送⾄内存,并通知内存要写⼊数据;CPU通过数据线将数据送⼊指定的内存单元;内存地址空间:每⼀个外部器件都有⾃⼰的存储芯⽚(如显卡有显存RAM和ROM(装有显卡BIOS)、⽹卡ROM(装有⽹卡BIOS)),CPU控制各个设备都是通过总线向各个设备的存储芯⽚发送命令,存储芯⽚根据CPU的命令控制外设进⾏⼯作所有的物理存储器被看作⼀个由若⼲存储单元组成的逻辑存储器,每个物理内存在这个逻辑内存中占有⼀个地址段,即⼀段地址空间可看出各存储芯⽚都和CPU的总线相连;CPU对它们的读写都通过控制线发出内存读写命令CPU根据读取不同的地址实现对不同设备的读写操作,这个逻辑存储器就是内存地址空间,它的容量受CPU寻址能⼒的限制(即地址总线宽度限制),如有20位的地址总线宽度,它的寻址能⼒为2^20个内存单元(⼀个存储单元为1字节(8位))所以该CPU的内存地址空间的⼤⼩为1MB;32位地址线宽的CPU内存地址空间最⼤为为4GB(CPU不⾏的话加内存条也没得⽤!64位的就不得了了,主板不够插)1、CPU寻址能⼒ = 2^线宽2、⼀根数据总线传⼀位数据,8根数据总线⼀次传8位数据(1Byte)第⼆章寄存器CPU组成:运算器(信息处理)、控制器(控制各种器件进⾏⼯作)、寄存器(信息存储)内部总线实现CPU内部器件的联系外部总线实现CPU与主板和其他器件的联系AX、BX、CX、DX通常⽤来存放⼀般性数据——通⽤寄存器(后⾯是X的寄存器是16位的,现在的EAX前⾯加了个E是32位)这四个寄存器都可以分为两个独⽴的⼋位寄存器使⽤(如AX可分为⾼位AH和低位AL),是为了向下兼容(只使⽤低位,⾼位填0)单独使⽤时当成⼀个来看,同时使⽤时是整体(计算⽅法 2^[位数] )⼀个字=两个字节=>⼀个⼗六进制数,所以⼗六进制数的⼀位相当于⼆进制数的四位汇编指令不分⼤⼩写16位结构的CPU具备以下特征(64位同理):1、运算器⼀次最多可以处理16位的数据;2、寄存器的最⼤宽度为16位;3、寄存器和运算器之间的通路是16位的;8086CPU给出物理地址的⽅法:8086有20位地址总线,可传送20位地址,寻址能⼒为2^20 = 1M,⽽8086内部为16位结构,他只能传送16位的地址,表现出的寻址能⼒只有64,说明CPU不能直接传送16位数据地址到20位的总线上(资源浪费),所以需要转换成20位的地址;8086采⽤⼀种在内部⽤两个16位地址合成的⽅法来形成⼀个20位的物理地址(段地址和偏移地址),经过地址加法器转换成20位的物理地址,⽰意图:地址加法器的⼯作原理:物理地址 = 段地址SA*16+偏移地址EA & 物理地址 = 基础地址 + 偏移地址相当于把段地址往⾼位进了⼀位,这⾥说的16位是⼆进制的数,CPU中存储的数据只能是⼆进制,⽽我们表⽰地址是⽤16位的数字,前⾯说了2和16进制的转换关系,⼀个⼗六进制数的位等于四个位的⼆进制数,所以段地址乘以16,把段地址后移了⼀位,增加了⼀位16进制数,⼆进制就得加四位,即数据左移四位(⼆进制位),16+4=20位,转换完成⼀个数据的X进制形式左移1位,相当于乘以X(⼗进制数乘⼗后左移⼀位)⼀个数据的⼆进制形式左移N位,相当于该数据乘以2的N次⽅段落的概念:内存本⾝并没有被分段,分段概念来⾃于CPU,8086CPU⽤物理地址 = 段地址*16+偏移地址的⽅式给出内存单元的物理地址,使得我们可以⽤分段的⽅式来管理内存⽤段地址x16 定位段的起始地址,⽤偏移地址定位段中的内存单元注意:1、段地址X16必然是16的倍数,即⼀个段的起始地址也⼀定是16的倍数2、偏移地址为16位,16位地址的寻址能⼒为64k,所以⼀个段的长度最⼤为64kCPU访问内存单元时必须向内存提供内存单元的物理地址(有地址才知道要访问哪⾥)CPU可以⽤不同的段地址和偏移地址形成同⼀个物理地址(段地址+偏移地址都等于物理地址)偏移地址EA为16位,变化范围0~FFFFH,仅⽤偏移地址来寻址最多可寻64k个内存单元(如段地址位1000H,那么CPU寻址范围为:10000H~1FFFFH储存单元的地址⽤段地址和偏移地址描述:数据在21F60中 a、数据存在内存2000:1F60单元中;b、数据存在内存的2000段中的1F60中;(可将地址连续、起始地址为16的倍数的⼀组内存单元定义为⼀个段)段寄存器:提供段地址,8086CPU有4个段寄存器:CS(代码(指令)段寄存器)、DS(数据段寄存器)、SS(堆栈stack段寄存器)、ES(附加段寄存器)CS和IP(指令指针寄存器)是8086CPU中最关键的寄存器,存放CPU当前要读取的指令的地址在任何时候,CPU将CS为指定(存放)指令的段地址(代码段⾸地址),IP指定(存放)指令的偏移地址(指令从哪处代码开始执⾏),CS和IP经过地址加法器加⼯后(通过输⼊输出控制电路)从地址总线指向内存单元读取指令,指令再通过数据总线(经过输⼊输出控制电路)传递给指令缓冲器,再到执⾏控制器,实现执⾏效果内存中被CPU执⾏过的代码必然被CS:IP指向过1. 从 CS : IP 指向内存单元读取指令,读取的指令进⼊指令缓冲器2. IP = IP + 所读取指令的长度,从⽽指向下⼀条(即所指向的指令执⾏完后接着运⾏接着的下⼀条指令)CPU加电启动或复位时,CS=FFFFH,IP=0000H,即CPU刚启动时读取并执⾏的第⼀条指令是FFFF0H修改CS、IP值的指令:转移指令 jmp1. 同时修改CS、IP的内容:jmp 段地址:偏移地址(例:jmp 2AE3:3)2. 只修改IP的内容:jmp 某⼀合法寄存器(jmp ax),⽤寄存器中的值修改IP代码段:根据需要,将⼀组内存单元定义为⼀个段:把长度<=64kb的⼀组代码存在⼀组地址连续、起始地址为16的倍数的内存单元中(个⼈理解为偏移地址需要16位的位置),这段内存⽤来存放代码,从⽽定义了⼀个代码段(代码段不能影响CPU来是否执⾏它,还是得看CS:IP所指向的内存单元中的内容为指令,代码段仅仅是⼀种编程格式)所以要将CS:IP指向所定义的代码段中的第⼀条指令的⾸地址debug命令:R 查看、改变CPU寄存器的内容(修改寄存器中的值:r [寄存器名])D 查看内存中的内容( d 段地址:偏移地址)E 改写内存中的内容U 将内存中的及其指令翻译成汇编指令T 执⾏⼀条机器指令A 以汇编指令的格式在内存中写⼊⼀条机器指令第三章寄存器(内存访问)字单元:存放字型数据的内存单元⼀个字等于两个字节,⼀个字节等于8⽐特,则⼀个字型数据有16位;因为有两个字节组成,字可分为⾼位和低位,图中0和1可组成⼀个字,1位⽐0位⾼,所以他们组成的字,⾼位是4E,低位是20即4E20(可以直接⽤字的起始地址描述它,如0地址字单元)任何两个地址连续的内存单元,可以将其看成⼀个内存字单元,⼀个为字低位字节单元,⼀个为字⾼位字节单元DS寄存器和 [address]DS寄存器:⽤来存放要要访问数据的段地址(⾸地址),配合 [ EA ] 使⽤,[ ] 说明操作的是⼀个内存单元,EA为偏移地址,段地址为DS中存放的地址数据段:将⼀组长度⼩于64k、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从⽽定义了⼀个数据段;具体操作时⽤ds存放数据段的段地址,在根据需要⽤相关指令访问数据段中的具体单元栈(stack):出⼊栈规则LIFO(后进先出)⼊栈:push 出栈:poppush 寄存器 pop 寄存器push 段寄存器 pop 段寄存器push 内存单元 pop 内存单元内存空间是如何被当做栈使⽤的:每执⾏⼀次⼊栈指令,都会将寄存器的内容放⼊栈顶单元的上⽅,此时段寄存器SS、寄存器SP就会存放栈顶的地址及偏移量,任何时候SS:SP都指向栈顶元素,执⾏push和pop时,CPU从SS和SP中获取段顶地址⼊栈时:SP=SP-2 (⼊栈时由⾼位往低位⾛)出栈时:SP=SP+2 (出栈时由低位往⾼位⾛)注意:⼊栈时的偏移量SP的取值要⽐当前栈最⾼位+1位(如要⼊栈⾄1000E~F(即栈最底部的字单元地址000E),SP值应⽐F⾼⼀位0010栈顶越界:需⾃⾏根据所安排的栈⼤⼩进⾏出⼊栈,避免⼊栈数据太多越界,也要避免空栈的时候继续出栈导致越界;越界会覆盖或修改掉可能是其他程序的内存数据或指令,需要注意!push执⾏时,CPU改变栈顶的指向,即SP=SP-2,再将数据传⼊SS:SP指向的字单元中;pop执⾏时,CPU先读取栈顶指向的字单元数据,再改变SP,即SP=SP+2;可见push、pop指令修改的只是SP,栈顶的变化范围为:0~FFFF栈操作机制:SS:SP指⽰栈顶;改变SP后写内存的⼊栈指令;读内存后改变SP的出栈指令Debug的 T 命令在执⾏修改寄存器SS的指令时,下⼀条指令也紧接着被执⾏(mov ss,ax ; mov ss,[0] ; pop ss)可⽤段寄存器表⽰内存单元的段地址:第四章汇编程序编写汇编源码----编译连接----可执⾏⽂件(包含由汇编指令翻译过来的机器码和源程序中定义的数据以及相关的描述信息,如程序⼤⼩,占⽤多少内存空间等)伪指令:段名 segment ;定义⼀个段,该段从此开始:段名 ends ;该段从此结束end:汇编程序结束的标记assume:含义为“假设”,假设某⼀段寄存器和程序中的某⼀个⽤segment…ends定义的段相关联,⽤于说明关联的关系。
正确表示:mov ax,[bp]
(1)错误表示:mov ax,[ds], mov ax,[cx]
(2)在内存单元表示的[...]这种形式下,中括号里面只能放bx,si,di,bp 这四个寄存器。
1.bx,si a.bx,di b.bp,si c.
bp,di d.正确组合:(1)mov ax,[bx+bp]a.mov ax,[si+di]
b.错误表示:
(2)在“[...]”里面的寄存器只能是固定的四种组合,其他组合是错误的
2.如果在[...]中包含了bp 这个寄存器,那么默认的段寄存器就是ss
3.8.1 bx 、si 、di 和bp
从机器指令的层面来讲,并不关心数据的数值是多少,而关心在执行指令之前,它将要处理的数据存在在什么位置
1.CPU 内部
(1)内存
(2)端口
(3)处理的指令可以存放的位置有三个:
2.8.2 机器指令处理的数据在什么地方
立即数。
直接在指令中给出,执行指令前一刻,和代码一起存储在CPU 的指令缓存器中(1)eg.mov ax,1
寄存器 eg.mov ax,bx
(2)段地址(SA )和偏移地址(EA ) eg. mov ax,ds:[3]
(3)汇编语言中数据存储的位置有三种声明方式:
1.8.3 汇编语言中数据位置的表达
8.4 寻址方式
在之前的笔记已经整理了——>所有的寻址方式
8.5 指令要处理的数据有多长
mov al,bl (1)mov ax,bx
(2)通过寄存器名
1.mov word ptr ds:[0],1(1)inc byte [bx]
(2)通过“X ptr [...]”的格式,其中X 为word 或byte
2.pop ax (1)push bx
(2)默认或者已经规定(栈操作都是以字为单位)
3.汇编语言中通过三种方式声明所处理的是字还是字节
8.6 寻址方式的综合应用
暂时跳过
div reg(寄存器)
(1)div 内存单元
(2)格式:
1.运算规则与涉及到的寄存器
2.例:计算10001/100
3.由于10001>65535,所以被除数需要用DX 和AX 联合存放。
即使100<255,除数也必须取16位的,也就是把8.7 div 指令
第8章数据处理的两个基本问题
2019年11月10日17:54
由于10001>65535,所以被除数需要用DX 和AX 联合存放。
即使100<255,除数也必须取16位的,也就是把100放在一个16位的寄存器或者放在连续的两个内存单元。
db
字节型数据8位dw 字型数据16位
dd 双字型数据32位
8.8 伪指令dd
dup 是一个由编译器识别处理的操作符,用于定义重复的数据
1.例:
2.db 3 dup('abc','ABC')
3.即:'abcABCabcABCabcABC'
格式: X 重复的次数dup (重复的X 类型数据),其中X 可以为8.8小节中的任意一种
4.8.9 dup。