汇编语言(完结)

汇编语言

汇编语言-基础知识01

因为他是在硬件上面的编程语言,效率高

image-20210706115959671

比汇编更低级的就是i机器语言

image-20210706120127112

image-20210706130338381

image-20210706131304692

MOV 把后面的传给前面

image-20210706131759039

寄存器,是cpu中存储数据的器件,一个cpu有多个寄存器

image-20210706131940275

汇编语言,对吧,给了编译器。

C语言先编汇编,再变成编

image-20210706132420120

汇编语言的组成-基础知识02

image-20210706150412476

image-20210706150426583

只有与或非,只认识01

+ 一个与 一个 或

汇编的核心是汇编指令

jump 啦之类的

image-20210706150732252

cpu和内存的关系

image-20210706150854817

1.5 指令和数据

image-20210706151033133

1.6 存储单元

image-20210706151339820

image-20210706151445780

1.7 cpu对存储器的读写

image-20210706152107122

BUS 叫做总线

image-20210706152118912

image-20210706152131857

不单止内存条,网卡内存条,等等都行

写入

image-20210706152255933

指令和数据-基础知识03

image-20210707105809673

image-20210707105906614

因为有三总线,所以就能把指令和数据很好的区分开来

image-20210707110213325

我们拆开总线看看,

地址总线-------一定会被转成地址

image-20210707110259307

64位的cpu,64位的操作系统,64位的软件,才能进行64位

要不然都会向下继承,变成32了

地址总线

image-20210707110518185

他是 1011 看的时候肯定是从高位到低位对吧,

然后,他就会定位到1011这个地址去

image-20210707111105456

image-20210707123824207

宽度也就可以说他多少位

内存单元就是一个Byte

1 byte =8bit

一位就是一个数据

64位就能走8个字节喽,

数据总线

地址总线是来确定位置

image-20210707124232296

数据总线越宽,高速公路越快呗

image-20210707150853180

举个例子,这个89D8 数据如何传输?

8088cpu 每次传输8位

image-20210707150948717

这个是D8

小的传过去,1101 1000

再把高位传过去 1000 1001

8086cpu 一次是16位

image-20210707154032686

一次全部传输,

1101100010001001 数据宽度不断增加,使得cpu 越来越快

二级缓存,寄存器的增加,越来越快

控制总线

image-20210707161147222

对吧,对越多端口进行控制

image-20210707162241131

粗略理解一下,第一个,控制显示器,第二个控制内存之类的

image-20210707162705615

小总结

image-20210707162928974

基础知识04

截屏2021-07-07 下午10.46.53

每一个cpu都有自己的指令集,固定的几个就是处理什么的,他就不需要进行运算了,加快了速度

(3)有了cpu,必须要有数据交换的场所,也就是内存,也就是cpu的缓存,

怎么区分不同的数据呢?放在不同的总线上,就是不同的数据。/不同的指令

截屏2021-07-07 下午10.49.33

存储单元从0 进行存储

一个存储单元可以存储 8 位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1yjFXNRx-1625713417928)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210707225223.png)]

管脚都可以和总线相连

地址总线的宽度决定了cpu的寻址能力

数据总心啊的宽度决定了cpu与其他器件一次的数据传输量

控制线的宽度决定了cpu对系统中其他器械的控制能力

截屏2021-07-07 下午10.57.32

课后题

截屏2021-07-07 下午11.01.09

8kb ==8 *1024 B ==2^3. 2^10. 一共十三

第五题,二的十几次就完了,

1024 /4 除以他一次传输的即可

基础知识05

内存地址空间(概述)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QjGwMTPj-1625713456330)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210708094603.png)]

主板

截屏2021-07-08 上午9.47.38

接口卡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hjoLFdvz-1625713456334)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210708095108.png)]

cpu不能直接控制外部设备,而是通过接口进行操控,

网卡,对吧cpu控制网卡,然后和网线进行交流

各类存储器的芯片

存储器就是四个轮胎,c pu是马达

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyWto7oR-1625713456335)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210708095246.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KEwHxsxO-1625713456336)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210708102718.png)]

寄存器CPU工作原理

image-20210708165859137

8086之后都是x86

cpu 概述

一个cpu由运算器,逻辑控制器,寄存器,器件构成,也是靠总线相连,有内部总线。

image-20210708170001037

image-20210708170114174

寄存器概述,

8086cpu 有14个寄存器,

他可以和存储器进行配合工作,x相加

把111放在 AX中

把2222 放在BX中

运算器,将ax bx相加,存在cx中

他有8个通用寄存器,他们增加的寄存器也就是对浮点数的优化,

通用寄存器不能修改,否则会影响系统。

image-20210708170736004

x86 系列,的通用寄存器,都是16位,能存两个字节

image-20210708170919844

image-20210708171454830

32位CPU 的话就是 EAX 他的AX和上面还是一样的

16位寄存器的存放情况

image-20210708171538333

image-20210708171634425

00000000010010

image-20210708171710272

image-20210708171732493

因为是从0开始算的,所以,我们需要-1

image-20210708171905711

16位是跨时代的产物,8位不行,

段地址+偏移量

image-20210708172233099

他需要向下兼容,不然就会被淘汰

AX 可以分为AH和AL AH高位,AL低位

人分高低,【狗头】

image-20210708172305925

只要是8位的,直接AH填0

image-20210708172425481

兼容之前的系统,

image-20210708172435097

全写0

image-20210708172658308

这俩都是独立使用的

image-20210708172738044

单独的需要一个一个看,

合起来的话就一起看

字在寄存器中的存储

一次读取16 位就是字

一个字节 8 位

一个字 就是 两个字节

image-20210708174306614

image-20210708174317087

如果是每个字节,他就是两个,

如果是字,他就是一个16位,也就是20000

关于数制的讨论

image-20210708175316028

数制,只有01010101011010101 我们不喜欢二进制,

人类习惯于16进制

image-20210708175430206

16进制 一个就能打四个

8进制的话 一个能打三个

image-20210708175542508

bin 一般放的源码,源程序

binary

几条汇编指令

image-20210708175657789

== 汇编指令不区分大小写 ==

mov AX,18

image-20210708183349632

mov 78 送进ax的高位

add 增加,把8加到AX中,

逗号,是从后面往前面的,对吧

image-20210708183557676

思考题

image-20210708183723638

相加,满16进1对吧

image-20210708184844237

但是他超了,超了16位,但是,还在,AX中只能存放044c

第二道思考题

image-20210708185124298

分了al ah

image-20210708185519877

不是 0185H

al 和ah没关系,就算超了也不会填到ah中

他只有0058

如果这里写成ax,这儿就是0158H

image-20210708185629775

分开看的话,就会抛出去

image-20210708185646050

,如果这么容易丢弃进制值,他就会很容易造成溢出

监测点2.1

image-20210708190544819

F4A3h

31A3H

3123H

ax 6246h

6246

image-20210708191120150

第二问:mov ax ,0002h

​ add ax,ax

​ add ax,ax

​ add ax,ax

2.4 物理地址

image-20210708192044893

对,他访问物理地址,他就是一个一维,一直延申对把

16位结构的CPU

image-20210708193616373

image-20210708193649982

8086 外部又20个地址总线,能够寻址 1M

内部为16位,只能送16 2 ^16 = 64kb

image-20210708194012329

image-20210708194110106

16 位 段地址,16 位偏移地址,通过加法器,

image-20210708194234250

地址加法器 工作原理

image-20210708194251031

image-20210708194308034

×16 就是向左移动一位

image-20210708195958222

二进制移动4位 十六进制移动一位对吧

二进制左移一位,成2

十六进制左移一位,成16

十进制 成10

image-20210708200335650

成16 是左移4 位

image-20210708200454225

短地址*16+偏移地址=物理地址本质含义

image-20210708200538951

image-20210708200614540

image-20210708200754399

第一个,直接给物理地址

第二个,放不下,闹成了,基础地质+偏移地址

image-20210708201354492

image-20210708201403394

因为放不下,所以这么干

2.8 段的概念

截屏2021-07-08 下午10.54.54

因为是无奈之举,内存并没有被分段!!

截屏2021-07-08 下午10.55.28

可以认为一个段,也可以认为两个段,他是强加给他的,

但是总体还是一个,截屏2021-07-08 下午10.56.50

段时看需要而定,CPU的话,他就是整一个开始,

tips

截屏2021-07-08 下午10.57.46

截屏2021-07-08 下午10.58.20

一个段的长度最长就是2^16

能够偏移的最大也就是64k

截屏2021-07-08 下午10.59.42

CPU访问内存单元,必须向内存听过内存单元的物理地址

8086CPU在内部用段地址和便宜地址移位相加,最终形成物理地址。

思考小问题

截屏2021-07-08 下午11.01.28

一个物理地址是固定的,他有很多条路通向他

条条大路通罗马对吧

截屏2021-07-08 下午11.02.27

跟破解一些东西,有相似之处

截屏2021-07-08 下午11.02.48

截屏2021-07-08 下午11.03.39

偏移地址16 位,最多也就是64k对吧

截屏2021-07-08 下午11.05.10

对吧,也就是,定段地址,直接左移动一个,那就是1000h~1ffffh

没有小结的小结

截屏2021-07-08 下午11.05.58

同时还有两种描述方法

监测点2.2

截屏2021-07-08 下午11.08.13

第一个:

0010H +0000H

0010H + ffffH == 1000fh

第二个

SA * 16

20000H == x + SA *16

x最小0000 sa极最大,2000H

x最大ffff。 sa 就最小。 1001h

1001 因为,20000 -ffff /16。 有余数的话+1

第三问:

小于1000h

段寄存器

image-20210709153510926

8086有四个段寄存器,

code sixx 代码段地址寄存器

data 数据段

si 堆栈段

extra 附加段地址寄存器

CS和IP

image-20210709153740702

IP是cpu内部偏移地址寄存器

他俩特别关键,他俩指示了当前读取指令的地址。

image-20210709154344200

image-20210709154623365

CS和IP合成20位的地址,通过输出输入电路

地址总线输出,

找到内存20000

image-20210709154656398

然后他这个地址包含了三个字节,

因为mov 指令需要有三个字节

image-20210709154742408

拿到他的数据

image-20210709154754333

B82301

B8 是 mov

从下往上看 0123H

image-20210709154917202

放入指令缓冲器执行之后,就AX覆盖儿了

同时IP进行了修改+3

image-20210709155502041

image-20210709160432586

没有数据的,只要两个就能完成,

有数据的必须要三个

8080PC简要描述

image-20210709160838377

如果,这样的话,我们可以将 木马,放在 内存 杀软之前,对吧,就可以先加载你的木马,再加载杀软

image-20210709161321789

CS和IP

如果内存中有被执行过,肯定被csip指向过

image-20210709161633665

我们只能对寄存器做手脚,对吧,通过修改寄存器中的内容,进行控制

通过控制csip

就能控制他执行的目标指令的地址

image-20210709161757187

mov指令, 被称传送指令,mov可以改变csip的值?

当然不行,8086提供了更改好的修改csip值的指令

转移指令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jlz7wL5y-1625821081806)(…/…/AppData/Roaming/Typora/typora-user-images/image-20210709161909016.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kZmk1QFV-1625821081806)(…/…/AppData/Roaming/Typora/typora-user-images/image-20210709161938449.png)]

想要同时修改csip的内容,

那就是

jmp 短地址:偏移地址

第一个 2AE33

第二个 0B46H

image-20210709162614123

合法寄存器就是 通用寄存器

jmp ax

首先,mov ax , 200h

然后就是,jmp ax 也就是 jmp 200h的意思

jmp bx

image-20210709163217368

image-20210709163656468

答案

image-20210709163704672

image-20210709163726508

代码段

image-20210709164032609

image-20210709164210223

两个十六进制 可以代表一个字节

如何使得代码段中的指令被执行

image-20210709164459008

csip指向,即能执行

不能拿ds来指定,因为他会被认为成数据

csip指向的就会被认为指令!

image-20210709164638456

暴力破解

image-20210709164726070

跳过注册阶段,csip指向之后

小截

image-20210709164749196

cs,ds,ss,es,

image-20210709164851423

或许,如果,指向 ,一个图片,他也是0101 他会认成其他的汇编指令,就会造成报错

image-20210709165211158

image-20210709165220740

监测点

604ff1690efd814ffc97cbdd4c50f2cimage-20210709165255017

实验一

image-20210709172412284

debug,调试工具,也可以进行写程序

程序是调出来的,

image-20210709172616133

win10 没有debug

image-20210709174502976

有20多个个指令,本次实验就六个指令

R

R ax

1111

会改成 1111

image-20210709174818032

image-20210709174901788

修改 IP cs

​ -t 执行一条指令

怎么看呢?

1400 1111 0000 这四个没内容所以是0000

D命令查看内容

image-20210709175310934

image-20210709175459894

成功改值

image-20210709175540617

修改ip,cs,查看内容,然后执行

image-20210709175604924

b440

实验任务

image-20210709175653228

image-20210709175727612

image-20210709175734621

E 和A

E: 改写内存的内容

A 以汇编格式 在内存中写一条机器指令

image-20210709175821593

现在内存的情况

image-20210709180129746

将这些写入,

mov很明现,他跳了三个,对把

没值,跳了两个

image-20210709180310704

-d 找到我们输入的地方

-u展示成汇编

image-20210709180417815

正如我们刚刚闹得地方

我们把csip指到程序的开始

image-20210709180607490

image-20210709180632331

用T 命令执行,看内存

image-20210709180706164

很明显,ax覆盖了他

下一条,ax加了1416对吧

image-20210709180910300

image-20210709180944939

然后bx变成了2000

image-20210709181920514

其他任务

image-20210709182429983

发现直接指不行,我们用jmp跳过去

好像不用,直接

image-20210709182955021

ax变8了

-a 直接改写

image-20210709183051979

image-20210709183446689

寄存器(CPU工作原理07)

-t 执行一条命令,对吧,需要先拿-r 修正一下cs 和ip

方便跳转过去

截屏2021-07-11 下午3.36.26

2^8

需要16禁制,

不断执行即可

截屏2021-07-11 下午3.39.03

试图改改看?

-d ffff0:0

直接看就可以,它翻译成了ASCII码截屏2021-07-11 下午3.40.40

范围

image-20210711154900635

-e 往内存里写数据,

-a 往内存里写指令

image-20210711155214346

这俩其实是一样的,对应的一个地址对吧。

同时因为,rom bios 寄存器内,一般改写不了

09 年 1月 19 日

image-20210711155325659

第四题

image-20210711155432499

突然出现了一个红桃,砖块,

B8100 他是一个 显卡,显存的地址,改成啥他的屏幕就会变

一般用masm,别用ida,熟练了以后,可以用masm

宁可学windows api 编程,也别学mfc。他是工具!!!!

寄存器(内存访问)

第三章讲的是,寄存器和内存的互动

image-20210711160803049

目录~

一个字就是两个字节,对吧,也就是8位

DS 数据段寄存器 和【address】 他是偏移地址

字的传送

mov, add, sub 相减的指令

数据段

栈:特别好的发明,(栈溢出),造成了不少漏洞

栈顶越界的问题么,~

push pop 指令,两个对栈的操作

引言

image-20210711161021705

内存中字的存储

想要存放20000 这个数据

4e20

高位对应高地址

低位对应低地址

高地址,存放, 高地址对吧,存了4e

image-20210711161145460

image-20210711161156093

0地址单元,存放的字节型数据是多少?

以字节为单位,一个单元存放的一个字节,那就是20H他存的数据是32

0地址字单元中,存放的字型数据是多少?

(4E20)

2地址字单元中存放的字节型数据是多少?

**单元或者是字节单元,他说的是一个框,而,字单元,他说的是两个框 **

image-20210711161426350

image-20210711162408127

image-20210711162626391

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hV7aZkQj-1626070563009)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210711162920.png)]

一个结论

3.2 DS 和【address】

ds存放的是段地址

image-20210711163225458

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dPEVWmzP-1626070563010)(…/Library/Application Support/typora-user-images/image-20210711163243734.png)]

image-20210711163333579

image-20210711170311011

mov al,【0】

截屏2021-07-11 下午5.19.41

ds只会读取地址,而不是数据

image-20210711172519076

image-20210711172534185

mov a l,[0]

就是把,偏移地址为0的内容送到al寄存器

image-20210711173734157

我们这样做的话,

image-20210711173931112

1000h 移动到bx

bx 移动到ds

ds中有了段地址,

然后mov al,「0」

他就会自动将 段地址的,第零个偏移地址,给了al

image-20210711174109316

【0】。也就是上面那个

image-20210711174120519

image-20210711174129845

总体解释

image-20210711174334436

那么问题来了,如何把1000H 送入ds

我们不能把地址,直接传给ds,我们必须要通过通用寄存器,才能将,地址传给ds,他CPU设了限制

image-20210711174533257

不支持将数据直接存入段寄存器

硬件设计的问题

image-20210711174843732

数据 -》 通用寄存器〉段寄存器

image-20210711174949250

从,寄存器送入内存单元!!!

image-20210711175331085

当然,图中是错的!!!!!!

mov。bx ,1000h

是将内存单元的内容送到寄存器了,现在是需要将寄存器的内容送到内存单元中

目测肯定需要一波ds喽~~

结论!!

image-20210711175506257

字的传送

image-20210711175738899

image-20210711175813486

前两行,段地址,

image-20210711175853327

那么,为什么不是么,字节类型呢?

因为ax是16位的啦

如果是ax 的话么,他【0】 默认存过去的就是16位的数据

那么高位存放到1001。

低位存放到1000

image-20210711180233473

问题3.3

image-20210711180321994

ax 填入 1000h

然后段地址改为了1000h

然后

将 10000h中的值给了ax

ax值为 1123

bx值为6622

cx值为2211

加到bx。 6622+2211

加到cx。 2211 +6622

image-20210711180411116

主要是注意,ax 他是 两个 字节,一个字

字的传送

image-20210712111409630

image-20210712111419958

写一波例题

image-20210712111603232

-e 直接存进来

image-20210712112130953

把指令写进去

image-20210712112923035

image-20210712132450099
把值输入到里面

我来脑子调试一波

ax 1000h

ds 1000

ax 等于 11316(2c34)

11316 填入 1000 0

10000h 34

10001h 2c

bx == 2c34

bx = 2c34-1122

实际情况,如下

image-20210712133244447

输入完成以后,来冲

image-20210712133359814

image-20210712133411126

image-20210712133510902

bx 也是2C34

SUB 相当于 bx = bx -【2】

image-20210712133614900

image-20210712133747279

存储方式也是如上面所说

第三章 寄存器(内存访问)03

mov add sub 指令

image-20210712133908830

mov的形式

image-20210712134206200

mov 的五种形式 第六种如下,也可以的

推测

image-20210712134315051

image-20210712134522591

覆盖完成,可以

image-20210712134553412

很多指令,用多了就会了,

汇编金手指 查就行了

image-20210712134902415

image-20210712135139582

em,我这里报错了,你们呢?

image-20210712135236638

image-20210712135258004

image-20210712135517651

最早是8位,然后就是一个字节

出现了16位,就是出现了字(CPU)

出现了32位,就是出现了双字(cpu)

现在道乐64位,就出现了四字

image-20210712135856978

image-20210712135905718

image-20210712135918803

image-20210712140116755

和我想的一样对吧~

add ax,[0]

add ax,[2]

add ax,[4]

image-20210712140342471

ax,0书上错了刚

image-20210712140405943

小结

image-20210712140445750

image-20210712140535660

image-20210712140737773

小甲鱼另一种形式报错了

但是这样可以

mov ax,2000,【x】

image-20210712141321903

image-20210712140609404

image-20210712140842600

字的传送

image-20210712111409630

image-20210712111419958

写一波例题

image-20210712111603232

-e 直接存进来

image-20210712112130953

把指令写进去

image-20210712112923035

image-20210712132450099
把值输入到里面

我来脑子调试一波

ax 1000h

ds 1000

ax 等于 11316(2c34)

11316 填入 1000 0

10000h 34

10001h 2c

bx == 2c34

bx = 2c34-1122

实际情况,如下

image-20210712133244447

输入完成以后,来冲

image-20210712133359814

image-20210712133411126

image-20210712133510902

bx 也是2C34

SUB 相当于 bx = bx -【2】

image-20210712133614900

image-20210712133747279

存储方式也是如上面所说

寄存器(内存访问)

第三章讲的是,寄存器和内存的互动

image-20210711160803049

目录~

一个字就是两个字节,对吧,也就是8位

DS 数据段寄存器 和【address】 他是偏移地址

字的传送

mov, add, sub 相减的指令

数据段

栈:特别好的发明,(栈溢出),造成了不少漏洞

栈顶越界的问题么,~

push pop 指令,两个对栈的操作

引言

image-20210711161021705

内存中字的存储

想要存放20000 这个数据

4e20

高位对应高地址

低位对应低地址

高地址,存放, 高地址对吧,存了4e

image-20210711161145460

image-20210711161156093

0地址单元,存放的字节型数据是多少?

以字节为单位,一个单元存放的一个字节,那就是20H他存的数据是32

0地址字单元中,存放的字型数据是多少?

(4E20)

2地址字单元中存放的字节型数据是多少?

**单元或者是字节单元,他说的是一个框,而,字单元,他说的是两个框 **

image-20210711161426350

image-20210711162408127

image-20210711162626391

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iPiCMqwA-1626169233338)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210711162920.png)]

一个结论

3.2 DS 和【address】

ds存放的是段地址

image-20210711163225458

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RLt8XFW7-1626169233340)(…/Library/Application Support/typora-user-images/image-20210711163243734.png)]

image-20210711163333579

image-20210711170311011

mov al,【0】

截屏2021-07-11 下午5.19.41

ds只会读取地址,而不是数据

image-20210711172519076

image-20210711172534185

mov a l,[0]

就是把,偏移地址为0的内容送到al寄存器

image-20210711173734157

我们这样做的话,

image-20210711173931112

1000h 移动到bx

bx 移动到ds

ds中有了段地址,

然后mov al,「0」

他就会自动将 段地址的,第零个偏移地址,给了al

image-20210711174109316

【0】。也就是上面那个

image-20210711174120519

image-20210711174129845

总体解释

image-20210711174334436

那么问题来了,如何把1000H 送入ds

我们不能把地址,直接传给ds,我们必须要通过通用寄存器,才能将,地址传给ds,他CPU设了限制

image-20210711174533257

不支持将数据直接存入段寄存器

硬件设计的问题

image-20210711174843732

数据 -》 通用寄存器〉段寄存器

image-20210711174949250

从,寄存器送入内存单元!!!

image-20210711175331085

当然,图中是错的!!!!!!

mov。bx ,1000h

是将内存单元的内容送到寄存器了,现在是需要将寄存器的内容送到内存单元中

目测肯定需要一波ds喽~~

结论!!

image-20210711175506257

字的传送

image-20210711175738899

image-20210711175813486

前两行,段地址,

image-20210711175853327

那么,为什么不是么,字节类型呢?

因为ax是16位的啦

如果是ax 的话么,他【0】 默认存过去的就是16位的数据

那么高位存放到1001。

低位存放到1000

image-20210711180233473

问题3.3

image-20210711180321994

ax 填入 1000h

然后段地址改为了1000h

然后

将 10000h中的值给了ax

ax值为 1123

bx值为6622

cx值为2211

加到bx。 6622+2211

加到cx。 2211 +6622

image-20210711180411116

主要是注意,ax 他是 两个 字节,一个字

课后题

image-20210713174303943

段地址,是害羞的!

image-20210713174442257

问题3.8

image-20210713174812908

Mov ax,1000h

Mov ss,ax

Mov sp,0010H

mov ax,001Ah

mov bx,001Bh

push ax

Push bx

Mov ax,0

mov bx,0

pop bx

Pop ax

如果是系统中,他比较喜欢xor ax,ax。异或 一样为0 不一样为1

相当于放到栈里,保存了一下,然后取出来接着用~

image-20210713184830396

image-20210713185122026

image-20210713185142353

出入栈顺序相反~

3.9

image-20210713185305350

mov ax,1000

mov ss,ax

Mov sp 0010h

mov ax,002a

mov bx,002b

Push ax

push bx

Pop ax

Pop bx

这不就交换了吗~

image-20210713185509583

问题3.10

image-20210713185618597

image-20210713185642744

image-20210713185952595

image-20210713190024267

image-20210713190036656

push 分为两个步骤

先➖2在放进去

image-20210713190153616

image-20210713190403578

高级语言,这些事情都是由编译器来做的(防止栈溢出)

image-20210713190816902

image-20210713190853534

image-20210713191120047

tips

sp 修改的是偏移地址,~

image-20210713191149040

一个栈最大是64kb喽~

栈的综述

image-20210713191506564

image-20210713191531149

也就是写内存

image-20210713191558714

也就是读内存

image-20210713191658930

所以我们可以骗他对吧~

image-20210713191827255

栈,非常重要~~~

image-20210713191842439

3.10 栈段

image-20210714140852368

根据需要,自己定义段 就数据段,代码段一样

我们能讲 一段,起始地址为16的倍数,ji的内存单元 当栈

image-20210714141803745

image-20210714141850437

CPU只认识 ss:sp 栈顶,cpu 其他不管!

他只认push pop

image-20210714142005315

image-20210714142030329

问题3.11

image-20210714142038426

ss=1000h

sp=ffffh

也不是+2,而是指向他下一个单元

sp=0000

就比如 10000h-----1000fh

栈顶~~~~·0010h

image-20210714142618518

image-20210714142823168

他最底部的字单元,就是ffffeh

image-20210714143010088

image-20210714143026992

问题3.12

栈段最大多少?

64kb么

2^16

image-20210714143557145

image-20210714143643324

超了64kb就会覆盖原来的内容

早期,堆栈用来保存返回的地址

(栈 临时存放东西)

方便函数调用

调用完以后,局部变量就不见了,被释放了

image-20210714144003010

cpu 一条线

|

|

|
|
|
|

image-20210714144101505

image-20210714144114172

image-20210714144145457

image-20210714144304040

image-20210714144310700

都是我们自己安排的

image-20210714144323745

image-20210714144455979

相当于10000 -----10001f

栈和他代码段重复了!!!1

数据段也重复了!!!!!1

image-20210714144803147

image-20210714144900713

image-20210714150205030

image-20210714150929564

监测点3.2

image-20210714145018472

image-20210714145105116

image-20210714145111175

首先,数据段寄存器变成了1000

mov ax,2000h

mov ss,ax

mov sp,10h

第二题

mov ax,1000h

mov sp,ax

mov ss,0000h

第一个程序!!

image-20210714175625234

image-20210714175701240

运行exe

一个源程序从写出到执行得过程

image-20210714175727223

编写汇编源程序

image-20210714175741483

nodepad就行啦~

image-20210714175838950

image-20210714175847366

image-20210714175858406

可执行文件

连接之后就会生成可执行文件

image-20210714180030570

image-20210714183754368

首先都是初始化,对吧,把机器码和数据载入内存,然后初始化,(比如设置cs:ip指向第一个要执行的指令,然后cpu执行

首先,写源代码,程序

然后 编译链接起来

然后再由我们执行

image-20210714184026808

源程序

image-20210714184119434

assume cs:codesg

codesg(代码 段)segment

start    开始

codesg ends

end


image-20210714184334958

h

image-20210714184437661

除了汇编指令其他就是伪指令

image-20210714184452363

最终不被cpu执行

image-20210714184501763

编译器是识别伪指令的,

image-20210714184539836

segment和ends 是成对使用的伪指令。是必须要用到的一对伪指令

image-20210714184902202

如果足够小的话,可以把点exe改成点com,(只有一个段那种,也是可以执行的)

image-20210714185040953

image-20210714185103537

end 是真正的没了

image-20210714185135063

最后的伪指令

image-20210714185227800

image-20210714185230574

不要记混这几个!!!!

assume

假如,假设,(含义为假设)

image-20210714185347962

assume 假设,代码段寄存器,叫 codesg,当然也可以改名字!

源程序中的程序

image-20210714185729600

也就是,由计算机最终执行的指令或者结果

伪指令: 编译器处理的,那里结束哪里开始,哪里指向cs,哪里指向栈段

汇编指令 可以直接编译为机器码

编译后的,哪些程序是程序

image-20210714190920324

image-20210714191016809

源程序经过编译,变成程序

编译完后成为PE文件

如果不确定pe头,那他肯定估计就一堆机器码,啥也找不到

中间灰色是编译器

image-20210714191632026## 标号

image-20210714191716501

这个段的名称,最终会被编译链接程序 处理为一个段的段地址

怎么命名无所谓,他是会成为一个唯一的地址,标识他的唯一一个段,叫标号

image-20210714194355384

image-20210714194708304

小任务~~

assume cs:abc
abc segment
	mov ax,2
	add ax,ax
	add ax,ax
abc ends
end

我们假设,cs和abc关联,编译器会将,abc处理为一个地址,让cpu默认为是一个cs代码段

程序返回

image-20210714195350908

dos中的程序运行

我们知道dos单任务操作系统,看电影不能聊qq

image-20210714195718504

windows 实现了多任务系统~

image-20210715104349306

p2 再可执行文件中,必须有一个正在运行的p1 将 p2哦菜呢个可执行文件中加载进内存,将cpu控制权给了p2 p2才能运行P2运行,p1暂停

image-20210715104513999

image-20210715104613063

现在,一个程序结束后,将CPU的控制权交还给使他运行的程序,

我们称之为 程序返回

如何返回呢?需要加上返回的程序段~

image-20210715104755182

dos最出名的就是中断机制

消息机制是windows多任务的开始

段结束,程序结束,程序返回

image-20210715104917113

语法错误和逻辑错误

image-20210715105041976

asume 他就不认识,就是语法错误!

image-20210715105059181

逻辑错误,是你打错的,编译器不会发现错误

!!!不容易发现!!!1

image-20210715105242372

!!!masm!!!

image-20210715105800270

后缀asm

选择,assmbly 汇编语言

image-20210715110555617

粘贴过来~

image-20210715110735543

有severe errors 有一些错误~

很难受= =兄弟盟

image-20210715110811087

image-20210715110959381

编译完成~!!

masm 1.asm

image-20210715111034442

如果报错的话,就会提醒你哪儿错了!

编译完成,然后需要进行链接

image-20210715111150795

obj都是机器码的信息

link 1.obj

image-20210715111221164

他会提醒,没有代码段,没有一个入口地址,

image-20210715111250866

image-20210715111530641

运行完又会回来,因为他,中文字符,所以会乱码~

image-20210715111552137

image-20210715111756002

加了分号,他就不会有任何废话的确认!

image-20210715111815239

我们使用masm 和link的缩写

ml.exe

image-20210715111909522

自动生成~

image-20210715112012452

编译:将伪指令,汇编指令转换为机器码

链接:

image-20210715112046257

image-20210715112106268

image-20210715112148422

image-20210715112238481

关于编译和链接

image-20210715112301482

image-20210715112513199

编辑器:notepad++ ue winhex

编译器:masm

连接器 :link

调试工具:debug

第四章第一个程序03

在这里插入图片描述

芜湖,复习一下

可执行文件中的程序装入内存并运行的原理

image-20210715114533402

image-20210715114844909

第一个:cmd

image-20210715115413225

怎么让他知道是哪个程序呢?,设置csip 指向程序的入口

image-20210715115745003

image-20210715115713799

image-20210715115454514

返回到cmd喽

操作系统的外壳

image-20210715115513117

汇编程序从写出到执行的过程

image-20210715115806967

image-20210715124250348

单步调试,执行一次,中断一次

我们编译一个有入口的

image-20210715124738004

他不提示了,说明有入口了!!

image-20210715124859889

image-20210715124929083

这样都可以,并不是一定需要写成start,他只是认为,end 之后的叫入口的地址

image-20210715125317619

我们进入 2.exe

image-20210715132021582

通用寄存器,存放的是 程序的长度

第一条对吧 mov ax ,0123

image-20210715132317017

image-20210715132354237

我们该查看哪个寄存器?ds,cs?

image-20210715132413647

程序执行过程的跟踪

image-20210715135241094

exe程序加载的过程

按理说,cs,ds应该指向同一个地方,对吧,但是实际上不是

image-20210715135346371

image-20210715135403123

加多一个0 相差100

首先,她找到一个段地址,称之为SA,肯定够加载的,在前256字节中

也就是16进制的100H

创建一个PSP 一段空间,这段空间存放dos利用他和加载程序之间的通讯

这段内存,反而是从SA+10H开始的

image-20210715135924237

SA+10H:0

SA:100H

他这两个,就是同两个段,方便程序员理解存放的不同的内容

image-20210715140209598

image-20210715140249995

csip还是从程序真正开始的地方

前256个字节,存放的是psp的内容

image-20210715140435839

我们看段寄存器开始指向,他就是,psp

image-20210715140504829

我们看csip,就是我们程序的指令

image-20210715140550263

小总结

image-20210715140658509

image-20210715140709425

image-20210715141119226

image-20210715141135698

image-20210715141205259

4.9 程序执行过程的跟踪

image-20210715141232203

image-20210715141256197

用p命令来结束

image-20210715141345378

执行啦

image-20210715141417917

相加

image-20210715141506686

相加

执行mov ax,4c00

image-20210715141544569

image-20210715141601053

要使用P命令执行int21

image-20210715141648315

image-20210715141810714

image-20210715141938611

image-20210715141955592

5.1[bx]

loop指令,循环呗~

image-20210715144649627

【bx】是什么呢?

image-20210715145513868

编译器中!并不是 debug的命令

你看 mov a1,【0】 等于mov a1,0

mov al,[2] 等于 mov al,02

debug和编译器是不一样的!!!!!!‘

image-20210715145637205

编译器不会这么认为对吧,

image-20210715145822631

ax一次一个字的传输

al一次一个字节的传输

image-20210715150958767

image-20210715151227203

【bx】就是用来给masm看的

不能mov ax,[0】对吧

那如果我们想给他东西怎么办

mov ax,[bx]

image-20210715151320798

先给bx赋值,然后再传

loop

image-20210715151705938

image-20210715151734530

image-20210715152234003

这个不就是

ax寄存器中的值,等于 ds中寄存器值左移一位,然后偏移两个,

image-20210715152407576

两个值相等了

image-20210715152432078

image-20210715152440367

image-20210715152511862

push/pop相反的哟

image-20210715152525406

约定符号idata表示常量

image-20210715152619629

5.1【bx】

image-20210715152718559

image-20210715152840865

这个是讲课采用的,不能这么写得哟

image-20210715152910475

mov [bx],ax

image-20210715153004854

问题5.1

image-20210715153023463

image-20210715153040383

image-20210715153443442

inc是自增1,相当于i++

image-20210715155403493

ax赋值2000

给了ds

然后bx 给了1000

然后21000的值给了ax

bx自增

bx自增

然后把ax值给了后两个的地方,210002

然后自增自增 又来一次 210004

然后自增

把高位给了

自增

把高位给了

image-20210715155845455

image-20210715155949050

image-20210715160000170

两次自增

image-20210715160058147

image-20210715160356291

倒着看才差不多

32个字节一个单位~~~

od来看内存的话,找到多大,在倒着看

image-20210715161235681

直接 p

5.2 Loop指令

指令的格式是:loop标号,cpu执行loop指令的时候,要进行两步操作

image-20210715170432972

就像pop push 一样,有两步操作

loop和cx有关系,~!!!!!

image-20210715170509310

image-20210715170535906

image-20210715170614412

如果为0就接着,向下执行

image-20210715170849580

cx中存放循环的次数!

image-20210715171251251

我们来看loop的作用

任务1 编程计算2^2

结果存放在ax中

image-20210715171328208

image-20210715171536163

任务二

image-20210715171640104

image-20210715171931648

任务三

image-20210715172420348

image-20210715172430511

image-20210715172620273

image-20210715172633094

image-20210715172641760

这个是标号,随便闹

说明他要执行循环11次

image-20210715172731931

image-20210715173431770

image-20210715173444106

不为零会跳转到标号

image-20210715173511367

image-20210715173540006

image-20210715174028191

image-20210715174033897

首先,直接,给他ax赋值,cx默认是程序的大小

cx赋值为b了

image-20210715174119939

image-20210715174155393

loop 0006 就相当于一个开始的地址,不管你叫啥,但是最后都会变成循环开始)

image-20210715174343202

image-20210715174357512

0 了,该接着走了

image-20210715174414018

image-20210715174643508

5.2 loop指令

image-20210715175838840

loop和cx配合的三个要点~

cx存放循环次数

loop指令中的标号,所标识地址要在前面;

要循环的程序段,要卸载标号和loop指令中间

image-20210715180217012

image-20210715180256258

循环体的内容~~·

loop s

image-20210715180507335

image-20210715180511965

image-20210715180638578

我们肯定不会这么干,

236 加123次多香呀

image-20210715180724545

在debug中跟踪用loop指令实现循环程序

我们当然可以存在dx中,那么,如果我们存储的数据超过这个会怎么样?!

image-20210715185922013

image-20210715190755074

image-20210715190833148

image-20210715191114514

image-20210715191045560

位数,只是让他,数据大小相等就行,管你听没听到·~~

image-20210715191321566

image-20210715193244351

image-20210715193259863

image-20210715193527336

image-20210715193602940

image-20210715193648742

为什么会,多一个零呢?

如果给[bx] 值的话 因为一个是8位,一个是16位,会发生奇奇怪怪的问题

image-20210715194012081

两句合成一句

如果删掉,会发生什么

image-20210715194457226

按理说是不能改的,因为改了的话,他这里只用读取8位,改了的话,不能保证ah高位一定是0

image-20210715194636350

这儿为什么要加0呢’?

image-20210715194832338

因为,汇编源程序,他不能以字母开头@!!!!!

image-20210715194901556

当场报错

!

如果有字母,直接就填一个0

image-20210715195000237

跟进一下,也就三个循环

image-20210715195021363

更能熟悉了loop的过程

image-20210715195031833

image-20210715195552767

当调试很多次的时候,

我们可以使用G命令,P命令

image-20210715195938786

占了25个字节

image-20210715200025485

image-20210715200141826

al ah要分开赋值

不能直接写

image-20210715200202203

书上是对的

image-20210715200303393

我们可以通过-g 直接执行到循环结束,

image-20210715200541755

循环,这里,-p直接回跳过,然后下一条语句,

温故而知新

image-20210716135340267

Debug和汇编编译器masm对指令的不同处理

image-20210716135659701

这里,他是根据源指令去取数据的,ax,【0】 就会从【0】开始去一个字16位

但是汇编源程序中,mov ax [0]===mov ax 0

image-20210716135839214

示例

debug中


mov ax,2000

mov ds,ax

mov al,[0]

mov bl,[1]

mov cl,[2]

mov dl,[3]

汇编语言

assume cs:codesg
codesg segment
wuhu:
	mov ax,2000h
	mov bs,ax
	mov bx,0
	mov al,[bx]
	
	mov ax,4c00h
	int 21h
codesg ends
end wuhu

-r 查看(改),-t 执行,-u 机器码翻译汇编

-d 查看ascii转码后的内容 -e 修改值

-a 写入指令

image-20210716141341763

是否可以像debug一样简单?

image-20210716141903197

这样就可以啦~~~

-p 跳过循环

-g 随便挑到哪一个地址,中间都会执行

image-20210716145213072

讲al 值给0

将0位置的值给al

将【bx]内容,给了al

将【bx]内容,给了al

loop和[bx]的联合应用

image-20210716145743363

超了就会损失精度

0-b是12个字节类型~

范围是0-255

12个相加,255*12 不可能大于65535 所以可以放存

image-20210716150102915

image-20210716150350464

可不可以这样呢?

image-20210716150417382

!! 类型匹配 结果不越界

image-20210716150716386

这俩不行

需要找中介

image-20210716150843926

image-20210716151206018

当然我们需要适用loop~

image-20210716151413232

image-20210716151458398

image-20210716151705045

我们需要变量对吧

image-20210716151736340

image-20210716151853975

image-20210716152923425

image-20210716152918083

打完了,调试一下

image-20210716153243579

偏移地址只能使用bx哟

使用cx什么的都不可以!

image-20210716153406752

image-20210716153410906

image-20210716153441081

如果给常量,就不能进行递增了!

image-20210716153549726

5.6 段前缀

image-20210716153717128

image-20210716153825161

这就是段前缀,如果前面没写,就默认放在ds中

一段安全的空间

image-20210716153938472

不能随便覆盖东西,不负责任!!

image-20210716154053093

image-20210716154108926

覆盖到人家数据,就会报错,欺负到操作系统了

image-20210716154253790

就像这样报错!

image-20210716154310396

a

image-20210716154433364

我们要更好的进行变成,理解系统底层

image-20210716154502218

操作系统把一切都封装好了,一个又一个的虚拟机,一个又一个的虚拟空间,

image-20210716154558967

image-20210716154626546

dos下,确实不会被操作系统所干扰

可能会改写系统数据,不安全

image-20210716154727852

这段空间中,百分之百没有任何代码,

image-20210716154739086

从0:200~0:2ff 的256个字节的空间,这段空间是安全空间

我们就写到这儿,不会被干扰

image-20210716154821112

image-20210716154859355

image-20210716155006335

5.8 段前缀的使用

image-20210716155042300

image-20210716155106936

这样的话就可以统一偏移地址~

image-20210716155223436

image-20210716155303039

image-20210716165503886

12次可以忽略,2亿次就不行了呀

image-20210716165525326

我们的es 附加段

每次循坏改两次,太麻烦了

这种优化策略,是十分重要的

改进的程序的分析

image-20210716165835315

使用es,优化,就不用重复设置ds

第六章 包含多个段的程序

我们为了编程简单,编程方便,我们就会分段

引言

image-20210716180515060

C语言,一个一个函数,一个一个段~

面向对象:一个功能,一个类一个类的调用

函数的封装

封装使得变成更简单~

image-20210716181023315

系统会给的~

我要200个字节零花钱,他就会给~~

image-20210716181116666

6.1再代码段中使用数据

image-20210716181215746

好歹放在一个地方一块而加

image-20210716181259376

解释dw

image-20210716181348378

如果说定义字节数据,也就是db 对吧就是define Byte

image-20210716181510679

分别为16个字节,每个都是16字节

英文逗号~

image-20210716181721094

8个数据在哪儿呢?

codesg在代码段,cs段

image-20210716181822345

因为dw定义的数据处于代码段的开始,所以偏移地址为0

image-20210716181848448

image-20210716182020918

image-20210716182041142

image-20210716182115775

我们编译,先不要运行,debug加载一下

image-20210716182533772

image-20210716182642334

开始可不行,start不能在dw上

image-20210716182716718

我们查看内存

image-20210716183039816

当然,查看的是段的开始

确实是存放的数据

image-20210716183342804

偏移16个字节后,真的就是开头

要运行,必须要入口

image-20210716183512295

image-20210716183517799

然后结束

image-20210716183530104

当然我们早打了

image-20210716193429383

当然,我们不能拿这个-u来看,因为,CPU他是把机器码识别成指令,所以都把他翻译成了指令,,csip没指向正确,肯定会执行错误

image-20210716194354223

end还会寻找编译器入口

6.2 在代码段中使用栈

image-20210719170218284

逆序存放,一般就要想到栈

image-20210719170400953

image-20210719170440699

image-20210719170458907

image-20210719170529219

首先,你定义了dw 0,0,0,0,0,0

腾出了8个字的空间

image-20210719171406062

image-20210719172255361

监测点6.1

image-20210719172336942

mov cs:[bx],ax

image-20210719174514812

mov ax,cs

36

pop cs:[bx]

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

image-20210719175659058

image-20210719175720405

怎么做呢

image-20210719175858420

一个封装的思路~

image-20210719175931326

image-20210719180249251

他将,数据定义为数据段,代码定义了代码段,栈定义了栈段

image-20210719180438254

data相当于是一个地址,相当于是一个段地址

image-20210719180519162

image-20210719180528874

image-20210719180627687

cpu是看不懂的

image-20210719180717992

image-20210719180727666

当然不会,他只是编译器知道的而已

image-20210719180916116

image-20210719180927430

end start 这个他会把start指向的当作代码段执行,

image-20210719180943835

image-20210719181046805

image-20210719181125411

image-20210719181226110

实验五, 编写,调试具有多个段程序

首先

debug加载,

image-20210719183713895

数据段,栈段,代码段

image-20210719183807776

end 后是开始标识

执行到21h,程序都加载完了, 那么就来查看一下值

image-20210719184716071

好,没变

stacksg segment stack 这样才可以指定栈段

,否则的话需要在代码段中指定

image-20210719185017633

第二题

image-20210719185241681

image-20210719190224705

调试完成

0B3D

0042

0B3E

0B3D

image-20210719190414605

没有发生改变

0123 0456

第一题,第二题,他的字型数据不同,数据量不同对吧,但是呢,第一题第二题地址一样!,奇奇怪怪的,

因为计算机是以16的倍数分配空间的,段总是16的倍数

image-20210719190705861

16 *(N/16 +1)

image-20210719190810769

比如,n 是 17 个,他肯定给两个,

image-20210719190914314

因为我们写的不同,所以,code data stack 三个的顺序大小不同噢,在程序中位置发生了改变

image-20210719191136695

编译器从上往下编译的

image-20210719191215308

只有第三个可以执行,他不知道从哪儿开始,他就会从头开始执行,

第五题

image-20210719191333888

MOV AX,A

MOV DS,AX

MOV AX,B

MOV ES,AX

MOV BX,0

MOV AX,C

MOV XS,AX

MOV CX,8

S: ADD DS:[BX],EX:[BX]

​	MOV CX[BX],DS:[BX]

LOOP S



MOV AX 4C00H

INT 21H

也可以A先放C,然后c+b

第六题

image-20210719192110646


MOV SS,B

MOV AX,A

MOV DS,AX

MOV SP,16

MOV BX,0

PUSH DS:[BX]



引言

image-20210719232055545

没有目录的目录

image-20210719232114009

7.1 and 和 or指令

image-20210719232205737

and指令 逻辑与指令,按位进行与运算

image-20210719232246277

两个为1 ,其他为零

两个1 才为1。只要有0 就是0

and al,00111011b

将后面的数据和前面进行与运算,

按位进行与运算

and指令的一点功能

image-20210719232447447

image-20210719232454827

and 可以将相应位数设置成0

or指令

逻辑或指令,按位进行或运算

image-20210719232923762

0|1 = 1

零零相或才为0,其他全是1

image-20210719232905692

or指令的一点功能

可以将相应的位设为1

其他位置不变

image-20210719233019432

ASCII码

image-20210719233456210

全世界统一的 ascii。(8位)

unicode 也是(包含中文,韩文,日文)

unicode 包含 ascii

image-20210719233617722

image-20210719233638275

image-20210719233705891

61 h表示。 97。 也就是a

关于ascii码表续

image-20210719233743410

image-20210719233752335

以字符形式给出的数据

image-20210719233905157

单引号,

image-20210719233917634

image-20210719233934912

db 相当于是 字节

image-20210719234114455

大小写转换的问题

image-20210719235330329

大小写,相差32 也是相差20H

大写在前小写在后

image-20210719235438880

这个是16 jingzhi

小写字母在二进制中,第五位多了一个1

image-20210720001229818

image-20210720001242640

image-20210720001319727

程序必须要能够判断

image-20210720001343095

image-20210720001353144

image-20210720001440505

大写字母的第五位,都是为0

小写字母的第五位都是 1

image-20210720001527330

image-20210720001535190

image-20210720001635675

image-20210720001749444

大写改小写,or

小写该大写 and

7.5[bx+idata]

image-20210720140225993

更为灵活的方式

image-20210720140400992image-20210720140440014

image-20210720140528728

这三个从实质意义上来说是一样的

image-20210720140608818

问题7.1

image-20210720140625636

21000h给了ax

+1 给了cs

+1加到cx

image-20210720140829524

image-20210720140852342

image-20210720141012336

方便的对加一减一进行操作

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

image-20210720141812622

image-20210720141836686

image-20210720141853871

原版代码

image-20210720141922572

变第五位,是优化的重点~

image-20210720142411674

image-20210720142519988

image-20210720142619686

image-20210720142701184

image-20210720142928254

改进后的程序

image-20210720142947199

image-20210720143102345

记住,四种写的方式

image-20210720143233208

如果我们使用C,写出来就是这样的

image-20210720143335735

C和汇编,有类似之处

image-20210720143352137

SI和DI

这两个通用寄存器,si和di和bx功能相近

image-20210720143438341

image-20210720143554345

这俩一样~

bx不够用,所以我们补充si di

使用复制啦,循环啦,si di不够用

image-20210720143642677

image-20210720143734942

问题7.2

image-20210720143749785

.。。。。。。 替换为字符

个人代码如下

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

image-20210720144244867

image-20210720144333091

问题7.2 分析嘘嘘嘘表

image-20210720144351578

si原始空间,di复制空间,这个是他答案

image-20210720144507245

image-20210720144737294

他只用了一个寄存器,

一次循环解决所有问题

[bx+si] 和[bx+di]

image-20210720144836428

两个寄存器,我门自己凑

这都可以

image-20210720144855391

image-20210720144911593

image-20210720144914714

image-20210720145017531

问题7.4

image-20210720145038756

image-20210720145152884

ax先00be

si+1

cx先0600

si+1

di变成06的位置

ax变成0006

si,di 可以当变化偏移地址

bx当起始偏移地址

7.9[bx+si+idata] [bx+di+idata]

image-20210720145733547

到底有什么方便之处

image-20210720145747018

image-20210720145757164

image-20210720145909507

只要常数在后面的,我们都要加点

问题7.5

image-20210720145941589

image-20210720145948680

image-20210720150010485

先ax 2000

给了ds

bx起始偏移1000

si 0

ax为0006

si+1

cx 6a00

si+1

di变为2

ax变为 226a

image-20210720150319932

7.10 不同的寻址方式的灵活应用

image-20210720151900780

本次解决例题

image-20210720151909028

image-20210720152006232

idata debug才认

【bx】 masm认

第三个相当于数组

image-20210720152117462

image-20210720152142485

image-20210720152218050

问题7.6

image-20210720152310022

datasg中的数据结构图

image-20210720153621553

后面都是空格填充!!!!!

image-20210720153733213

image-20210720153810032

要定位具体的大写

六行循环

一次处理一个大写

image-20210720153932393

image-20210720154038804

image-20210720154046836

image-20210720154316580

问题7.7

image-20210720154400959

每个单词改为大写,怎么办呢?

image-20210720154516110

image-20210720154546210

image-20210720154622335

image-20210720154645848

问题7.7 分析

image-20210720154656815

嵌套循环

image-20210720154828715

image-20210720162451648

image-20210720162532319

他的cx,两个,很明显,错了,

问题7.8

image-20210720163158159

昨天的程序

他会进入死循环,

内层也会改变cx

image-20210720164857354

image-20210720165617640

这儿直接溢出了,直接死循环

image-20210720165659698

loop 一定要配cx,而且不能多用一个寄存器

先保存,出来的时候,再恢复

所以猜测可以用栈?

image-20210720165743807

汇编中,dx临时存储cx

image-20210720165825532

image-20210720165848188

在进行外层循环的时候,恢复cx的值

image-20210720170020681

image-20210720170041240

CPU中寄存器毕竟是有限的

image-20210720170052579

image-20210720170112303

image-20210720170123095

我觉得可以栈~

image-20210720170317079

我们不能用寄存器了,我么可以用内存~

image-20210720170341995

image-20210720170347435

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O0nwkEJr-1626778558355)(…/…/AppData/Roaming/Typora/typora-user-images/image-20210720172111774.png)]

image-20210720172238326

image-20210720172247404

image-20210720172348986

我们先看vc编译器 的做法

image-20210720172417299

好,最后用栈,开心

image-20210720172513845

image-20210720172647652

image-20210720172806890

image-20210720172920916

他相当于,里面的东西没改

使得我们的栈,非常必要,使得有漏洞可循!

image-20210720175334873

image-20210720175351161

image-20210720175537115

问题7.9

image-20210720173117279

数据分布如下

image-20210720173129587

image-20210720173152045

image-20210720173158208

image-20210720173313054

image-20210720173414153

image-20210720173628095

第八章引言

image-20210720223240059

处理的数据,放在内存里面

要处理的数据有多长?

image-20210720223320839

image-20210720223412393

image-20210720223450924

reg 表示寄存器,sreg表示段寄存器,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ykk1g5Lv-1627282741131)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720223519.png)]

8.1 bx si di bp

前三个用过了,总结一下

image-20210720223629270

image-20210720223634711

只有四个,8086里面

【a x】这种就是错误的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tIvoMZVs-1627282741135)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720223644.png)]

image-20210720223704502

这四个寄存器,可以单个出现,也可以进行四种组合的出现

bx和si bx和di。 bp 和si。 bp 和di

image-20210720224129843

image-20210720224145927

image-20210720224727030

bp相当于sp,帮忙sp减轻负担的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YKzeyLx9-1627282741140)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720225950.png)]

bp 和bx不能在一起,因为会混乱

一个指向ss 一个指向ds 会产生歧义

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gg5hNEGD-1627282741142)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720230618.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rvgbqfvx-1627282741143)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720230739.png)]

image-20210720230754522

image-20210720230809993

汇编语言中数据位置的表达

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qEEwhS2W-1627282741146)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720230856.png)]

段地址:SA

偏移地址 :EA

立即数(idata)

直接包含在机器指令中的数据,执行前在cpu的指令缓冲器中!

image-20210720230932334

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hhbq3l5u-1627282741148)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231236.png)]

2 寄存器

image-20210720231254110

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cTNOdwKa-1627282741150)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231323.png)]

3.段地址(SA)和偏移地址(EA)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rCdo95fe-1627282741152)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231355.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FrHED7qZ-1627282741153)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231435.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wiwy4j0r-1627282741155)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231443.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0rwTMeny-1627282741156)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231611.png)]

0的话没有问题,其他就会报错

image-20210720231627037

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PfWfR924-1627282741160)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231710.png)]

image-20210720231720769

bp为什么会跟着ds了呢?

因为没有声明,他默认ss而已

这儿强制给出了

8.4 寻址方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZXoLbZgp-1627282741163)(https://gitee.com/dingpengs/image/raw/master/imgmac//20210720231824.png)]

寻址方式总结

image-20210720231907754

动画演示

1、直接寻址

image-20210720232057331

image-20210720232125332

指令要处理的数据有多长

通过寄存器名 指明要处理的数据的尺寸

image-20210721133827458

image-20210721133929503

因为是 bx 16 位,他会取值 ds:【0】ds:[1]

都是16位的寄存器,1就是0001H

image-20210721134048706

如果这里是al

就是低8位

也就是 1===01h、

在没有指明寄存器名存在的情况下,用操作符X ptr 指明内存单元的长度

x在汇编中可以为word 或者 byte

image-20210721134122453

image-20210721134222754

image-20210721134459933

规定字型,可以强制

image-20210721134520698

双字行,就是double word

image-20210721134555498

如果是 字节型数据的情况下

他的数据是(FFH) +1 会溢出

00ffh +1 0100h

如果是字的话,就不会溢出

image-20210721134755948

image-20210721134829797

修改的不一样噢

image-20210721134955033

其他方法

有些指令默认访问的是字单元你还是字节单元

image-20210721135023541

push 栈 默认只对字进行操作

sp=sp—2

8.6 寻址方式的综合应用

我们来一个实例

image-20210721135823737

image-20210721144353352

image-20210721143952940

image-20210721144040734

如上相当于伪代码

字符串 在内存里面就是字符型的数组

image-20210721144835472

这个 p 就是后续的改变,位置的变化

image-20210721144901311

他占了三个字节~

image-20210721144922811

image-20210721145008952

相对寻址~

image-20210721145021624

相对基址变zhi寻址

image-20210721145303959

C语言~

image-20210721145520952

image-20210721145525425

image-20210721145604085

这种叫做数据结构~~~~

image-20210721145703194

image-20210721145727045

image-20210721145754867

image-20210721145815619

div 指令

image-20210721145928530

div是除法~

除数,:8位,16位,在寄存器或者内存单元中

image-20210721150003487

被除数默认放在AX 或者 DX和AX中

都是用加法来模拟的

用乘法模拟除法,如何?

image-20210721150419730

如果除数是 8 位的话,

如果除数是16 位的话

image-20210721150524508

div示例

image-20210721150635482

image-20210721150812146

image-20210721150856494

注意这里

image-20210721151159113

编程

image-20210721151244535

1000

image-20210721151303917

image-20210721151333621

image-202107211514287151 存放在dx 86A1 存放在ax中

image-20210721151520785

编程程序2

image-20210721151624494

可以用ax寄存器存放

image-20210721151715948

8.8 伪指令dd

image-20210721151741253

image-20210721151745531

32 位

示例,定义按个数据

image-20210721152005532

问题8.1

image-20210721152020275

image-20210721152823479

image-20210721153001010

assume data:segment
		dd 100001
		dw 100
		dw 0
		data ends
start:
		mov ax,data
		mov ds,ax
		mov ax,ds:[0]
		mov dx,ds:[2]
		div word ptr ds:[4]
		
		mov ds:[6],ax
		
		
		
		
		mov ax,4c00h
		int 21h
data ends
end start

dup

image-20210721153420233

这不是指令,只有编译器认识

image-20210721153659537

image-20210721153807327

image-20210721153824328

image-20210721153831414

dup的使用格式如下

image-20210721153907701

image-20210721153922052

image-20210721153937968

我们要定义栈段~,如果不用dup就很难受

image-20210721153955174

引言

image-20210721174953286

无条件转移指令 如 jmp

条件转移指令

循环指令

过程(就是c语言的函数,函数也称为过程)

中断(例如,中断,原来的东西停下来,突然干其他事儿,cpu只能处理一件事情)

操作符offset

image-20210721175249431

伪指令,

功能是取得标号的偏移地址

image-20210721175308247

s是三开始,所以相当于mov ax 3

问题9.1

image-20210721175437415

mov bx,0

mov di:[bx],si:[bx]

上面是我写的,猜测可以结果不行

image-20210721175731841

image-20210721175745003

image-20210721175844230

1- 地点,2-长度

image-20210721192614905

9.2 jmp指令

jmp为无条件跳转,

image-20210721192750975

暴力破解

image-20210721192810911

9.3 依据位移进行转移的jmp指令

image-20210721192955820

jmp short 标号

这个是短转移

对 ip 修改为1B的范围,-128----127

负数往上跳

正数往下跳

image-20210721193056744

image-20210721193137452

image-20210721193159035

汇编指令与机器码的对应示例

image-20210721193205219

image-20210721193255303立即数会出现

image-20210721193341835

image-20210721193613850

image-20210721193618857

image-20210721194106308

他并没有08 为什么会这样呢?

因为 执行的时候,他并不知道 s的具体位置

image-20210721194130171

image-20210721194432824

我们添加了一个axax

image-20210721194446918

发现这里改变了

!!

03 变成了 05

只是在中间添加了 2字节

机器指令中 并不包含转移的目的地址

image-20210721194525858

image-20210721194602609

CPU不需要目的地址就可以进行IP的修改

image-20210721194623553

他的s存的是偏移地址

image-20210721200102022

image-20210721200156269

image-20210721200218735

image-20210721201236051

image-20210721201320423

段内近转移

image-20210721201354770

这儿是成了16位,之前是8位

image-20210721201436654

image-20210721204443727

EB 是jmp的机器码,

刚刚,ip指向了BB

image-20210721204635360

走完jmp。ip指向了 2000A

因为笨,只会把EB 后面的数加到ip上

0A + F6

加上 F6 变成了20000

image-20210721204804039

F6 是负数才对,-10

F6+10 正好是FF,补码简单的运算

向上要减少,向下要增加,

补码计算负数

源码 变反码 +1 变补码

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

image-20210722102609093

image-20210722102620808

上节课是相对地址,的转移

这个是远转移,会给你具体的地址~

image-20210722102845191

程序9.3

image-20210722102950172

image-20210722103137935

image-20210722103200571

010b就是跳了的s的地址

机器码需要 倒着看,EA是远转移

image-20210722103400230

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

image-20210722103520566

转移地址在内存中的jmp指令有两种格式

(1)

image-20210722103710620

jmp word ptr 内存单元地址(段内转移)

image-20210722103851514

也相当于 jmp ax

image-20210722104032910

(2)

image-20210722104257740

段间跳转,

目标段地址,和目标偏移地址

image-20210722104416103

image-20210722104532706

ds【2】ds【3 】取值0000

0 1 取值 0123H

image-20210722105102198

image-20210722105119724

监测点 9.1

image-20210722105338515

因为他跳的地方是取出了 data段的值

那我存0就可以

d 5 dup(0)

image-20210722105942139

相当于跳到1234段 5678ip对吧,

第一空 offset start我觉得可以,但是还是写0比较好,直接填入bx,因为没有内存和内存的通道

第二空 cs

image-20210722110847707

0006 00be

9.7jcxz指令

之前讲的是无条件跳转指令,

这个有条件跳转指令

image-20210722111047426

所有的有条件跳转都是短转移,都是相对偏移地址,

修改范围-128—127

loop 也是有条件跳转指令

image-20210722111239558

cx为0

image-20210722111342060

cx不等于0的时候,什么也不做

image-20210722111410820

监测点 9.2

image-20210722111448154

mov ch,0

mov cl,[bx]

jcxz ok

inc bx

因为这里是去找一个字节,所以要ch cl份开

9.8 loop指令

image-20210722113308955

image-20210722113350942

image-20210722113421855

image-20210722113524035

监测点9.3

image-20210722113551967

inc cx

image-20210722124247065

第九章 04 失踪了QAQ

第十章 call和ret指令

引言

程序之间加载返回过程

cmd调用debug,然后退出,然后返回

image-20210722223804704

段内转移 之用修改ip

段间转移。需要修改csip

image-20210722223854852

10.1 ret 和 retf

image-20210722223922977

image-20210722224036019

第一步,他把栈顶的值取出来,然后sp向下移动一个

image-20210722224019227

image-20210722224057794

image-20210722224419494

分析源码

image-20210722224449041

image-20210722224601693

亚栈,第一个为0

然后ret,他应该ip自动改为了0

跳到了结束,代码段的开始

image-20210722225008282

image-20210722225024055

retf指令

image-20210722225037774

image-20210722225052294

多了一个push cs

retf 先改ip,再改cs,还是回到了结束

image-20210722225307354

监测点10.1

image-20210726102529147

1000h

0000

10.2 call指令

image-20210722225431707

call不能实现短转移

call指令实现转移的方法和jmp原理相同,可实现近转移或者段转移

call 标号

image-20210722225834321

image-20210722225911865

压栈,

image-20210722225942599

image-20210722230007293

有负数 补码

image-20210722230202091

监测点10.2

image-20210726124721468

call s 会将 6 存入栈中,然后,pop ax,将栈中的值出栈给了寄存器ax

所以ax的值为6

10.4 转移的目的地址在指令中的call指令

image-20210725163021744

我们需要给相对地址,

我们本次学习 call far ptr 标号

image-20210725163049968

image-20210725163339665

call和jmp差不多,只是,call保存了当前的位置,

监测点10.3

image-20210726131727340

ax设置为0

远跳,1000,0008

0008+0008,然后pop bx,bx等于1000

然后就是1010h

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

格式指令:call 16位寄存器

image-20210725163746052

监测点10.4

image-20210726132307450

call 6

相当于跳到了6

然后把IP 5 存入栈中

然后你sp给了bp,就是把栈顶的指针拿了出来,【bp】 把栈顶的值取出来了

然后相加5+6 =11

10.6 转移地址在内存中的call指令

image-20210725164005132

word 段内跳转

dword 段间跳转

image-20210725164113285

image-20210725164539745

sp从何而来?栈顶指针么,10-2 0EH

第二种

image-20210725164707145

可以放两个通用寄存器~

高位cs,低位ip的吧(我自己假设)

image-20210725164752066

image-20210725164922384

因为你是出栈,执行的话,cs先0,ip后0123h

sp。0ch。

相对高位字节存放的cs,相对低位的字节是低寄存器

监测点 10.5

image-20210726133219891

第一题,前面不对ax有影响,应该是ax=3

image-20210726133243509

offset 相对于 代码段0地址的偏移量,

call 会push cs,push ip,然后

0ch存放的是,nop的ip

然后,就是 s ip减去 nop ip,,就相当于是1

0eh 的话,就是cs-cs肯定是0

10.7 call和ret的配合使用

问题10.1

image-20210725165113511

call 是 push ip,他把紧接着的一条指令的ip push到了栈

ret pop ip,相当于重新定位 到了mov bx,ax

bx = 8

image-20210725165835200

image-20210725165813037

小例题~

image-20210725165911780

请大家从栈的角度,分析一下call s

image-20210725165955703

10.7 call和ret的配合使用 2

我们看一下程序的主要执行过程

上节课的例题

image-20210725171505045

image-20210725171532910

image-20210725171616757

ip = ip +0005 = 0013h

为什么是5 呢

因为相对偏移地址

image-20210725171839100这样的话,正好是偏移五个

image-20210725172752514

ret 执行完后,ip指向 16

image-20210725172837330

image-20210725172943369

image-20210725172955275

一个call 对应一个ret。 不能多个

image-20210725173151924

image-20210725173207185

子程序调用对吧~

反汇编看一下

image-20210725173546018

这么长一堆就是初始化,

image-20210725173603663

他把 字符串 push 进去,然后去找到printf这个函数

add esp,4

这个是用来恢复栈的,因为push,把栈压低了,所以可以通过这个来恢复

后续会讲

image-20210725173722246

我们去调用这个函数,call这个地址

image-20210725173751283

然后会初始化函数对吧

image-20210725175706553

然后打印

image-20210725175720133

然后把push的恢复出来

最后ret,通过ret

返回主函数

image-20210725175756178

这里是,main函数的恢复阶段,然后我们继续ret,谁调用main函数,返回谁

控制台控制,就返回控制台呗

image-20210725175841604

什么语言都一样~

image-20210725175858310

ret到上一层,ret上一层

image-20210725180647561

10.8 mul指令

乘法命令

image-20210725180704831

image-20210725180714178

都是8位,都是16 位

image-20210725180752139

8✖️16 的话,可以把8位高位全天写0

image-20210725180853431

al 乘数,ax结果

image-20210725180959297

image-20210725181025168

例如

image-20210725181041259

必须要做 16 位乘法

mov ax 100 放在ax中,高位他会自动补0

image-20210725181117960

10.9 模块化程序设计

image-20210725181138967

庞大的程序,拆成小的方便修改

image-20210725181253325

这个是面对过程的思想

image-20210725182253716

image-20210725182336887

image-20210725182353084

可以用参数存到寄存器中

image-20210725182423335

默认16位乘,肯定没啥问题

我们需要进行注释,分号为注释

image-20210725182513847

10.10 参数和结果传递的问题

image-20210725182539271

image-20210725182701163

image-20210725182750132

代码块

image-20210725215906501

第二个是double word

image-20210725220031823

10.11 批量数据的传递

image-20210725220128484

我们多个参数怎么办呢?

8086cpu 寄存器有限哟

image-20210725220212998

image-20210725220224554

例题

image-20210725220236437

image-20210725220350231

image-20210725220358132

神奇~

image-20210725220531145

最好使用栈来传递参数

栈的性质和内存差不多

10.12 寄存器冲突问题

image-20210725221203622

image-20210725221234100

image-20210725221242607

image-20210725221358085

他看的是cx寄存器,

image-20210725221414831

将高把位设置0。低8位设置位字符串

image-20210725221457529

jcxz 检测cx为0 则结束

image-20210725222120955

套上一个循环即可

image-20210725222652843

image-20210725222555622

问题 10.2

需要调试一下~明天拿下

我觉得是因为cx的问题,

只有一个变量,应该放在栈中

image-20210725235402638

image-20210725235410133

实验十 编写子程序

image-20210725235522240

image-20210725235553790

image-20210725235709322

实验十讲解~

image-20210726202547452

showstr是我们的编写子程序

image-20210726202652005

image-20210726202714133

image-20210726203023494

实验一,放弃

实验二,读懂一下看看

image-20210726203143455

image-20210726203157651

image-20210726203318802

相当于普通除法, 余数是肯定不会比原来的大,所以不会溢出

image-20210726203132414

image-20210726203822604

子程序开始,先把ax存起来,说明后面ax会用到

ax是低16位

image-20210726204518121

16 位除法,默认dx为高16位,ax为低16位

image-20210726204636355

image-20210726204827039

image-20210726204856196

实验十 3

image-20210726204959091

image-20210726205014741

image-20210726205102944

image-20210726205119386

image-20210726205129530

输出show 和实验一一样

image-20210726205217613

结束程序之前都ok弹出栈

image-20210726205252498

image-20210726205739498

怎么将12666取出来呢?

image-20210726205343163

除以10 得余数

这里用了jcxz,判断商

数字加上30h就能得到对应的ascii码

目录

image-20210727100353529

引言

image-20210727100535369

image-20210727100605154

标志寄存器,就是

image-20210727100815170

每一位都有特别的信息

image-20210727100833057

image-20210727100944342

0246789 10 11 都有特殊意义

ZF标志

flag的第六位是ZF,零标志位

他记录相关指令执行后

结果位0 ZF=1

结果不为0,ZF=0

image-20210727101116855

例如:

image-20210727101134383

image-20210727101207619

0表示否定

image-20210727101243493

image-20210727132846238

image-20210727132909971

他们的运算会影响到标志寄存器

image-20210727132930662

有条件性的跳转,就需要拿这个来判断

11.2 PF标志

image-20210727144100706

查看二进制中1的个数

image-20210727144237352

11.3 SF标志

结果为负数,sf=1

结果为正 sf=0

image-20210727145648576

有符号数,补码

image-20210727145705510

有符号数,第一位为负数,然后变成补码,

补码。反码+1,我们先-1然后变源码,

1 1111111 肯定127

image-20210727150407982

image-20210727150446317

image-20210727150714238

image-20210727150735019

结果既可以是130 又可以-126

image-20210727150900846

SF标志记录数据的正负

image-20210727150929728

image-20210727151021688

image-20210727151035068

image-20210727151058502

都是约定好的

image-20210727151209504

监测点11.1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fTrrHfS6-1627456441904)(…/…/AppData/Roaming/Typora/typora-user-images/image-20210727151348810.png)]

ZF 是否为0

PF 1个数是否为偶数

SF 是否为负数

1,1,0
1,1,0(传送标志不影响)
push 传送标志不应i想
pop 不影响
al bl哪儿来的值??
确实 al为1,也就是
000
010

image-20210727161407587

11.4 CF标志

image-20210727153257157

image-20210727153334129

image-20210727153352576

image-20210727153536658

image-20210727153546150

之前 8位的话是无法处理的,当然不能这样草率的处理,

我们需要假象一个高位,当作进位

image-20210727153621267

image-20210727153701158

这些就是标志寄存器的特殊情况

image-20210727153721839

OF(overflow flag)溢出寄存器 NV(not overflow)

DF(direction flag)方向寄存器 UP(up)DN(dowm)向上下下

SF(sign flag)符号寄存器 NG(negtive)PL(plus)负数正数

ZF(zero flag)零标志 ZR(zero) NZ(not zero)

PF(parity flag)奇偶标志 PE(parity even) PO(partity odd) 偶数奇数

CF(carry flag) 进位标志 CY(carried) NC(not carried) 进位 不进位

image-20210727154020911

image-20210727154116120

image-20210727154141136

image-20210727154203048

这里表示游进位

标志位是表示上一条指令的,时时刻刻会在变化

image-20210727154343858

image-20210727154548087

这个也是借位的体现

11.5 OF标志

overflow 溢出 有符号可能产生的结果,进位是无符号可能产生的结果

image-20210727154752275

image-20210727155055420

image-20210727155129289

image-20210727155210230

如果针对于无符号数而言,这两个无所谓

如果阵对有符号位,这两个就会产生溢出

image-20210727155415736

示例二

这俩都是负数

image-20210727155438008

image-20210727155554478

对于有符号位发生了溢出

对于无符号位,产生了进位

image-20210727160318927

image-20210727160347379

image-20210727160422735

image-20210727160443606

image-20210727160627681

image-20210727160648237

因为计算机啥也不知道

image-20210727160738793

监测点11.2

11.6 adc指令

image-20210727160800600

image-20210727161250655

image-20210727161634546

image-20210727161654690

image-20210727161709946

关键是cf的值被谁设置的

image-20210727161726753

image-20210727161736824

这里是16进制相加减,这个1就是相当于cf加

image-20210727161929802

image-20210727165038055

提供adc就是为了加法第二步运算的

image-20210727165133785

image-20210727165144806

大家如果不理解adc的话

就来看这里

书中的adc求ax例子狗屁不通

adc就是用在高位加法,

比如这样

add al,al
如果产生了溢出,势必会导致cf为1
那么ah+ah的时候,
adc ah,ah,就会使得他进位被加上

编程任务

image-20210727175216564

这个是24位加减

我们需要把他拆开,

然后我们把高16位存在ax,低16位存在bx

加低的,然后产生进制

然后高位加

image-20210727175442847

adc论调

image-20210727175455375

image-20210727175510829

先加cx,adc bx,adc ax

image-20210727175537684

adc指令实践

image-20210727180204849

如果加的不够了,就可以放到内存/栈

image-20210727180223014

image-20210727183110430

这样是不行的,add指令会影响cf值,inc 不会影响

sbb指令

image-20210727183201591

带借位减法指令

image-20210727183215173

image-20210727191740742

先减低位,再减高位,能保证数据的完整性

image-20210727191822620

cmp指令

image-20210727191843978

只对标志寄存器产生影响,

image-20210727191858719

相当于减法指令,但是不会保存结果

image-20210727192129304

仅影响flag的各个位

image-20210727192144967

image-20210727192306213

只是改变了flag

image-20210727192507443

使用这个,我们可以进行爆破,不必进行运算,直接看flag,然后jmp或者jcmz跳

cmp的设计思路

image-20210727192743604

image-20210727192822265

image-20210727192830195

刚刚比较的都是无符号运算,

image-20210727193421941

cmp指令 有符号数

image-20210727193604426

判断是否相等,只看ZF就可以

image-20210727195154136

image-20210727195208342

image-20210727195245944

image-20210727195310425

image-20210727195342821

一个正数一个负数,会产生溢出错误

image-20210727195403748

小的减去大的得到负数

我们需要先加一个判断,判断大小?还是判断是否溢出呢?

image-20210727195442966

加一个判断溢出

image-20210727195508703

image-20210727195518617

有符号 考虑 sf,of

image-20210727195624061

image-20210727195633169

image-20210727195659555

image-20210727195703617

这样就可以是相反的

image-20210727195721727

只要产生溢出,结果就是相反的

image-20210727195731857

image-20210727195755266

32位都不存在段了

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

image-20210727200201191

image-20210727200228417

image-20210727200316996

image-20210727200327024

image-20210727200412484

image-20210727200444609

image-20210727200458460

image-20210727200511053

cmp指令配合je

编程训练

image-20210727200533930

cmp ah,bh

je s

add ah,bh

jmp short ok

s:add ah,ah

ok ret

image-20210727200652445

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

image-20210727200825058

image-20210727200828638

image-20210727200844409

image-20210727201122167

没有cmp,我们仍然可以进行gank

image-20210727201324299

image-20210727201330982

image-20210727201351657

image-20210727201400140

课堂练习

image-20210727201415996

image-20210727201419917

image-20210727201441435

image-20210727201449478

第二种方案

image-20210727201614329

image-20210727201652913

image-20210727201710738

方法一比较精简

image-20210727201748721

我们使用jna

image-20210727201759514

image-20210727201808847

image-20210727201819165

改成jnb

有符号和无符号只是对比的有一点不同而已

image-20210727201848501

image-20210727201853542

监测点11.3

image-20210728142307965

jb s0

ja s0

image-20210728142421502

jna s0

jnb s0

DF 标志 和串传动指令

image-20210727202600772

方向标志位

image-20210727202649862

image-20210727202658558串传送指令 以字节的形式移动

段地址为ds,偏移地址为si的内容 字节内容

把它放到,段地址为es,偏移地址为di的地址

df=1 被枪毙就是负数,不会混的

image-20210727202916301

movsw

image-20210727202925766

image-20210727202942386

和rep指令配合使用

image-20210727203007704

设置目标内存,来源内存,

可以循环实现cx个字符的传送,

image-20210727203230903

image-20210727203254347

cl :clear

st:set 对吧

DF 标志和串传送指令

image-20210728135509369

因为我们传输字符串,我们使用串传输指令

image-20210728140139372

image-20210728140145512

从哪来,到哪儿去,方向,长度

image-20210728140214473

DF =1的时候,就是负的

image-20210728140609668

image-20210728140817738

image-20210728140851794

确实复制过来了

编程二

image-20210728141019982

image-20210728141029679

DF设置成1也行哟

反方向存储u

image-20210728141215594

image-20210728141303754

image-20210728141445820

照搬,实现了

pushf和popf

image-20210728141523409

监测点11.4

image-20210728143559379

本题关键在于OF 标志的判断。另一个关键点是and 0000 0100 1100 0101 起到了屏蔽未学习位的作用!

mov ax,0 将ax置0

push ax,ax入栈

popf 将栈中的数据弹出道标志寄存器中,

00000000000000000000000000

mov ax,0fff0h

add ax,0010h

(ax) = fff0h+0010h

显然,10000 H flag 会发生改变

CF:假设为无符号计算,发生进位,CF=1

PF ax = 0000h pf标志为1

and 与运算,有0则0

assume cs:code
//奇怪之处ax的值为47h?使用指令pushf,popf
code segment
    start:
          mov ax,0
          push ax
          popf //从栈中弹出数据,送入标志寄存器,易知PSW将会被置为0
          mov ax,0fff0h
          add ax,0010h //结果为0000h,并发生进位,不溢出,此时寄存器的状态为NV UP DI PL ZR NA PE CY(即PSW:00000000 01000111,如果默认第01位为0则是01000101结果为45)
          pushf //将psw=47h值压入栈
          pop ax //将之前压入的值赋给al=47h(01000111)ah=0h(00000000)
          and al,11000101b //异与后al=45h(01000101)ah不变
          and ah,00001000b //异与后ah=0h(00000000)al不变
          mov ax,4c00h
          int 21h
code ends //所以ax最后值为45h

end start

第十二章 内中断 01

引言和简介

image-20210728152403430

image-20210728152408735

image-20210728152432743

这本书主要讲解硬件中断

外部中断主要是一i写,计算机外设发出的请求

image-20210728152506200

image-20210728152604494

就像int 21 就是软件中断

中断处理程序

除数为零,必须要来一个中断

为windows多任务,奠基

image-20210728153611722

image-20210728153705009

中断向量表

image-20210728153731292

image-20210728153753130就相当于是一个索引

image-20210728153839238

image-20210728153851448

中断向量表,从0开始,8086pc机

之前说的安全内存是 0:200----0:300

监测点12.1

中断过程

image-20210728154233469

image-20210728160003907

image-20210728160028520

image-20210728160044824

他要保存csip

image-20210728160128022

image-20210728160206141

中断处理程序

image-20210728160614603

image-20210728160702384

image-20210728160917976

调用中断一般都是用iret

image-20210728160950792

除法错误中断的处理

这个就是0号中断

image-20210728161221574

image-20210728174815821

编程处理0号中断

他修改了0号中断

image-20210728175117762

image-20210728175142960

image-20210728175307307

image-20210728175323771

image-20210728175331910

image-20210728175340036

image-20210728175346627

我们可以存放到安全的内存

image-20210728175557240

image-20210728175601812

image-20210728175611690

image-20210728175625114

image-20210728175841530

image-20210728180245658

这个存放的非常重要

image-20210728180322497

image-20210728180344076

image-20210728180348143

他是溢出的时候才会执行

image-20210728180357329

编程处理0号中断(2)

image-20210728180610669

我们把do0拷贝到安全区域,但是也不能执行,没有注册到中断向量表

image-20210728180652474

设置好后才能叫中断处理程序

image-20210728180708118

image-20210728180739386

image-20210728180829048

image-20210728190242775

image-20210728190532866

image-20210728190732867

image-20210728190741011

image-20210728190747048

image-20210728190751303

上面有减号,

image-20210728190814966

求出它们之间的距离

image-20210728190838557

编译器还可以处理其他的表达式

image-20210728190854603

image-20210728191006654

0b800 就是显存~

image-20210728191108739

image-20210728191117212

image-20210728191123128

看似合理,其实是错的

image-20210728191204629

image-20210728191222534

数据段可能会被覆盖

welcome 同ficshc 也许要放在安全的地方

image-20210728191258531

完整的程序实现

image-20210728191758254

单步中断

image-20210728191926648

image-20210728191933130

单步中断,为了控制

image-20210728192011884

debug却能停下来

image-20210728192028343

image-20210728192106209

TF位,就是单步中断

image-20210728192132905

指定了中断向量表

image-20210728192146916

image-20210728192230750

image-20210728192327853

原因就是为了实现单步跟踪

image-20210728192343335

响应中断的特殊情况

image-20210728192525457

发生中断他也不会响应??

image-20210728192548236

image-20210728192604430

image-20210728192658593

image-20210728192646883

image-20210728192706834

image-20210728192810740

image-20210728192828242

image-20210728193101091

image-20210728193111644

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值