|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
46 楼』:
【80x86汇编语言学习笔记】
根据测试,当调用了16位DOS程序以后,CMD 便被切换到了英文(美国)代码页:437,中文便无法显示了。
所以在代码中调用 Debug 来达到间接运行汇编代码功能后,当 Debug 退出后就进入了437代码页,给需要显示中文批处理带来麻烦。
如何既运行 16位 DOS 程序(如:Debug、Edit.com……等)还能正常显示中文呢?
解决办法如下:
@echo %dbg% off
:: 以下代码在批处理起始部分(在 @echo off 语句后面)
chcp 437|graftabl 936 >NUL
:: 后面的代码怎么用都可以 这样,再运行16位程序以及调用Debug完成特殊任务时,CMD窗口视觉上的大小不变、且正常显示中文。
(此刻不可以再输入中文了-CMD 输入法无效)
[ Last edited by redtek on 2006-12-19 at 12:22 PM ]
附件
1: 2.GIF (2006-12-20 01:21, 10.17 K, 下载附件所需积分 1 点
,下载次数: 1)
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-20 01:12 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
47 楼』:
【80x86汇编语言学习笔记】
) 这几天汇编语言学习总结:
学习汇编之前: 先学 Debug 基本使用等知识,可节省 70% 的入门时间。
否则,学习的陡峭曲线非常高,如再遇到一本破书又无师指导,很难坚持下去并自学入门。
开始学习汇编: 只学用得到的指令,用到再学,学的时候再找,会越学越深。
对汇编书或资料的选择: 选择错了书如是自学,等同于拜了小人为师,不仅付出10倍努力且还不得旨领。
往往这个时候就知难而退,有多少想学习汇编的人从此又放弃了。
什么汇编的书是好书? 一般的教学书均是归纳、总结、分类的次序书写,这种书不适书入门,适合学术。
要选择循序渐进的书做入门的书,往往一个概念得不到非常简明的解释,很可能又偏入岐途。
先有简单一个例子,或是按照从简到深的能力一点点推进的书,是好书。
没有 Debug 例子只有完全的理论的书是坏书。
要讲到事物本质的书是好书:
如:CPU是怎么执行指令的?
为什么段地址*16+偏移量……为什么要乘16?要它所有推出来的步骤…99%的书都没有。
高电平与低电平是如何代表指令的?
一个读内存单元的动作CPU与地址总线、数据总线、控置总线是如何配合工作的?
计算机中所有的设备(外设等)到底是怎么样的布局?如何工作的?(很多书都略掉了……)
这些本质上的东西如果略掉,只留下指令应该怎么写,又不给出本质,那么学也白学。
指令都是次要的,本质原理是最重要的。
如果完全自学,没有学校教、没有老师教,没有论坛可以请教,只有一台计算机、一些书,那么完全自学汇编的唯一要求
就是这本书要非常好,要讲本质并讲透,不断的想、编……
否则数十倍的努力去看那些破书并耗掉上百个小时,也不如好书里的一句话讲透了本质受用你一生的指点。
) 如何学好汇编?
刚学几天,不知道。
唯一感触非常多的就是,学的过程基础知识不能跳,表面上跳过去了后面也能看一部分,但到头来一定白学,还要回来。
这点我是真的感触到了,并且回过头来再重看、重学的时候对汇编的兴趣会丢掉一半……
) 以上个人学习汇编几天的总结,权当瞎说~:)
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-21 03:21 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
48 楼』:
【80x86汇编语言学习笔记】
从现在开始如果汇编基础知识不过关,就不再往后学。直到所有测试全部通过并理解以后再向后学习。
) 汇编语言基础知识测试
1、1个CPU的寻址能力为8KB,它的地址总线宽度为?
答: 8KB的寻址能力范围是: 0 ~~ 8191 B
n个二进制位的寻址能力的宽度是 2的n次方,所以 2的x次方=8192KB。
求得cpu的寻址能力为8kb,它地址总线宽度为 13。
即 2的13次方为 8192B(8192/1024=8KB)
2、1KB的存储器有多少个存储单元?存储单元的编号从多少到多少?
答:1KB的存储器有 1024 个存储单元,一个存储单元可存 8 个 bit,就是8个二进制位。
存储单元的编号是从0起始的,所以是 0 ~~ 1023。
3、1KB的存储器可以存储多少个bit,多少个byte?
答:1kb=1024B,可存 (1024B*8bit) 8192bit。
还可以存 1024 个 Byte。
4、1GB、1MB、1KB分别是多少 byte ?
答:1GB =(1024b * 1024KB)mb * 1024mb
= 1073741824 Byte
1MB = 1048576 Byte
1KB = 1024 Byte
5、8080、8088、80286、80386地址总线宽度分别为16、20、24、32根,它们寻址能力为_KB、_MB、_MB、_GB。
答:8080 为:64KB
8088 为:1MB
80286 为:16MB
80386 为:4GB
6、8080 8088 8086 80286 80386的数据总线宽度为8 8 16 16 32根,则它们一次可以传送的数据分别为多少B?
答:8080 为:256B
8088 为:256B
8086 为:65536B
80286 为:65536B
80386 为:4294967296B
7、从内存中读取1024字节的数据,8086至少要读多少次?80386至少要读多少次?
答:8086 CPU数据总线宽度是 8,即每次只能传递 8 bit 数据。1024字节需要读1024次。
80386 CPU数据总线宽度是32,每次传递 32 bit 数据,1024字节需要读256次。
8、在存储器中,数据和程序以什么形式存放?
答:数据和程序以二进制形式存放~:)
[ Last edited by redtek on 2006-12-20 at 03:42 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-21 03:52 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
49 楼』:
【80x86汇编语言学习笔记】
寄存器汇编指令练习:
Quote: | C:\TEMP\debug>debug
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC
0AF5:0100 3D0100 CMP AX,0001
-A
0AF5:0100 MOV AX,18
0AF5:0103 MOV AH,78
0AF5:0105 ADD AX,8
0AF5:0108 MOV AX,BX
0AF5:010A ADD AX,BX
0AF5:010C
-T=100
AX=0018 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 B478 MOV AH,78
-T
AX=7818 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0105 NV UP EI PL NZ NA PO NC
0AF5:0105 050800 ADD AX,0008
-T
AX=7820 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0108 NV UP EI PL NZ AC PO NC
0AF5:0108 89D8 MOV AX,BX
-T
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=010A NV UP EI PL NZ AC PO NC
0AF5:010A 01D8 ADD AX,BX
-T
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=010C NV UP EI PL ZR NA PE NC
0AF5:010C C28D8E RET 8E8D
-Q |
|
[ Last edited by redtek on 2006-12-20 at 04:06 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-21 05:04 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
50 楼』:
【80x86汇编语言学习笔记】
程序段中指令执行练习:
Quote: | -A
0AF5:0100 MOV AX,8226
0AF5:0103 MOV BX,AX
0AF5:0105 ADD AX,BX
0AF5:0107
-T=100
AX=8226 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 89C3 MOV BX,AX
-T
AX=8226 BX=8226 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0105 NV UP EI PL NZ NA PO NC
0AF5:0105 01D8 ADD AX,BX
-T
AX=044C BX=8226 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0107 OV UP EI PL NZ NA PO CY |
|
最后当执行 ADD AX,BX后,发生“溢出”,16位寄存器只能存放4位16进制数据。
试验2:
Quote: | 0AF5:0100 MOV AX,001A
0AF5:0103 MOV BX,0026
0AF5:0106 ADD AL,BL
0AF5:0108 ADD AH,BL
0AF5:010A ADD BH,AL
0AF5:010C MOV AH,0
0AF5:010E ADD AL,85
0AF5:0110 ADD AL,93
0AF5:0112
-T=100
AX=001A BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 BB2600 MOV BX,0026
-T
AX=001A BX=0026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0106 NV UP EI PL NZ NA PO NC
0AF5:0106 00D8 ADD AL,BL
-T
AX=0040 BX=0026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0108 NV UP EI PL NZ AC PO NC
0AF5:0108 00DC ADD AH,BL
-T
AX=2640 BX=0026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=010A NV UP EI PL NZ NA PO NC
0AF5:010A 00C7 ADD BH,AL
-T
AX=2640 BX=4026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=010C NV UP EI PL NZ NA PO NC
0AF5:010C B400 MOV AH,00
-T
AX=0040 BX=4026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=010E NV UP EI PL NZ NA PO NC
0AF5:010E 0485 ADD AL,85
-T
AX=00C5 BX=4026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0110 NV UP EI NG NZ NA PE NC
0AF5:0110 0493 ADD AL,93
-T
AX=0058 BX=4026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0112 OV UP EI PL NZ NA PO CY
0AF5:0112 E94EFF JMP 0063
-Q |
|
以上学习完了简单的加指令:ADD
测试: 只能使用学过的(MOV、ADD)这两条汇编指令,最多使用4条指令,编程计算2的4次方。
-A
0AF5:0100 MOV AL,2
0AF5:0102 ADD AL,AL
0AF5:0104 ADD AL,AL
0AF5:0106 ADD AL,AL
0AF5:0108
-T=100
AX=0002 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0102 NV UP EI PL NZ NA PO NC
0AF5:0102 00C0 ADD AL,AL
-T
AX=0004 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0104 NV UP EI PL NZ NA PO NC
0AF5:0104 00C0 ADD AL,AL
-T
AX=0008 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0106 NV UP EI PL NZ NA PO NC
0AF5:0106 00C0 ADD AL,AL
-T
AX=0010 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0108 NV UP EI PL NZ AC PO NC 结果10H(10进制的 16)。
[ Last edited by redtek on 2006-12-20 at 06:12 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-21 05:20 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
51 楼』:
【80x86汇编语言学习笔记】
( 16位CPU结构与物理地址计算 )
CPU结构特性:
运算器一次最多可以处理16位的数据;
寄存器的最大宽度为16位;
寄存器和运算器之间的通路为16位。
8086CPU有20位地址总线,可能传送20位地址,达到1MB的寻址能力。
8086CPU又是16位结构,在内部一次性处理、传输、暂时存储的地址为16位。
从8086CPU的内部结构来看,如果将地址从内部简单地发出,那么它只能送出16位的地址,表现出的寻址能力只有64KB。
8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
在 8086PC机中,存储单元的地址用两个元素来描述:段地址和偏移地址。
可根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。
形容一个地址的标准讲法~:)
(1) 数据存在内存 2000:1F60 单元中;
(2) 数据存在内存的 2000 段中的 1F60 单元中。
检测练习:
1、给定段地址为 0001H,公通过变化偏移地址寻址,CPU的寻址范围从哪里到哪里?
答: 0001H * 16 = 10H (段)
偏移量为16位,寻址范围为:0 ~~ FFFFH
段地址 * 16 + 偏移地址=物理地址
所以,CPU的物理寻址范围是: 10H ~~ 10FFFFH
2、有一数据存放在内存 20000H 单元中,现给定段地址为 SA,若想用偏移地址寻到此单元。SA应满足的条件是:
最小为?最大为?
答:范围取值过程:
--------------------------------------
1001H * 16 + FFF0H = 20000H
…… ……
1FFEH * 16 + 20H = 20000H
1FFFH * 16 + 10H = 20000H
2000H * 16 + 0H = 20000H
--------------------------------------
根据以上同理,已知:1000H * 16 + 10000H = 20000H 会发生16位溢出
推出计算公式如下:
( 20000H - FFFFH ) / 16 + 1H = 为 SA 段地址最小取值
所以,SA 最小取值为: 1FFEH
SA 最大取值为: 2000H
偏移量最小取值为: 0H
偏移量最大取值为:FFF0H
偏移量每次递增为: 10H
本想这道题不做了,昨天是绕进去了~:)
今天早上做的时候发现这道题得做,虽然做完了觉得简单。
做的过程中……一会儿16进制、一会儿又是10进制,来回来去的算……
当做完以后,发现了很多细节以及运算上以前没有注意到的地方。
深感基础必须扎实!基础越是扎实,后面的路就走得越远~:)
查看内存中的内容
根据资料给出:PC机主板上的ROM中写有一个生产日期,在内存 FFF00H~~FFFFFH 的某几个单元中,
请找到这个生产日期并试图改变它。
根据上面的计算原理,将物理内存地址“拆”成 段地址:偏移量 所表示的地址,使用Debug操作如下:
Quote: | -D FFF0:0000
FFF0:0000 EF 53 FF 65 F0 4D F8 41-F8 59 EC 39 E7 59 F8 2E .S.e.M.A.Y.9.Y..
FFF0:0010 E8 D2 EF 00 E0 F2 E6 6E-FE 53 FF 53 FF A4 F0 C7 .......n.S.S....
FFF0:0020 EF 00 00 5A EF 0F 07 F3-EE F3 EE F3 EE 18 07 F3 ...Z............
FFF0:0030 EE F3 EE 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:0040 00 00 00 00 00 00 00 00-E9 01 12 00 00 00 00 00 ................
FFF0:0050 CA 04 00 CF E9 33 EA 00-00 28 43 29 32 30 30 30 .....3...(C)2000
FFF0:0060 41 4D 49 2C 37 37 30 2D-32 34 36 2D 38 36 30 30 AMI,770-246-8600
FFF0:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
-D
FFF0:0080 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:0090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:00A0 00 00 00 00 00 00 00 00-00 00 E9 9F 11 00 00 00 ................
FFF0:00B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:00C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:00F0 EA 5B E0 00 F0 30 34 2F-30 32 2F 30 34 00 FC 00 .[...04/02/04...
-D
FFF0:0100 34 12 00 00 00 00 00 00-00 00 00 00 00 00 00 00 4...............
FFF0:0110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:0120 70 00 2E 8E 06 30 00 BF-7F 01 B9 02 00 AB 47 47 p....0........GG
FFF0:0130 E2 FB CB 56 50 51 52 57-55 1E 06 53 8B EC 8B 76 ...VPQRWU..S...v
FFF0:0140 12 2E 8E 1E 30 00 8B 44-02 A2 22 00 88 26 08 01 ....0..D.."..&..
FFF0:0150 8B 34 C4 1E 18 00 26 8A-47 01 26 8A 67 0D 26 8B .4....&.G.&.g.&.
FFF0:0160 4F 12 26 8B 57 14 97 26-8A 47 02 2E 3A 04 73 2C O.&.W..&.G..:.s,
FFF0:0170 98 D1 E0 03 F0 97 26 C4-7F 0E FC 2E FF 54 01 72 ......&......T.r
-D
FFF0:0180 02 B4 01 2E 8E 1E 30 00-C5 1E 18 00 89 47 03 5B ......0......G.[
FFF0:0190 07 1F 5D 5F 5A 59 58 5E-83 C4 02 CB E8 26 00 EB ..]_ZYX^.....&..
FFF0:01A0 E2 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:01B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FFF0:01C0 EA AE 10 A7 00 B0 03 C4-1E 18 00 26 29 4F 12 B4 ...........&)O..
FFF0:01D0 81 F9 C3 00 0B E1 01 E1-01 E1 01 D5 00 5C 01 9F .............\..
FFF0:01E0 01 E1 01 33 02 E3 01 E3-01 E1 01 1A E1 01 E1 01 ...3............
FFF0:01F0 E1 01 D5 00 44 02 AE 01-E1 01 E1 01 49 02 49 02 ....D.......I.I.
-Q |
|
[ Last edited by redtek on 2006-12-21 at 03:14 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-21 07:39 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
52 楼』:
【80x86汇编语言学习笔记】
寄存器与内存访问
存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。
高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。
任何两个地址连续的内存单元,N号单元和N+1号单元,可以将它们看成两个内存单元,
也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元。
DS,通常用来存放要访问数据的段的地址。
例如:要读取 10000H 单元的内容,可以用如下的程序段进行:
-A
0AF5:0100 MOV BX,1000
0AF5:0103 MOV DS,BX
0AF5:0105 MOV AL,[0]
0AF5:0108
-T=100
AX=0000 BX=1000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 8EDB MOV DS,BX
-T
AX=0000 BX=1000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0105 NV UP EI PL NZ NA PO NC
0AF5:0105 A00000 MOV AL,[0000] DS:0000=64
-T
AX=0064 BX=1000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0108 NV UP EI PL NZ NA PO NC 上面是读物理地址 10000H 单元内容,按 “段地址:偏移量” 来访问就是 1000:0000
因为其物理地址的计算为: 1000H*16+0000=10000H ,这个计算由CPU交给加法器来完成。
8086CPU不支持将数据直接送入段寄存器的操作(如: MOV DS,1000),这是非法指令。
所以只能按上面代码的间接用寄存器来进行中转操作。
测试:将 AL 中的数据送入内存单元 10000H
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC
0AF5:0100 B040 MOV AL,40
-A
0AF5:0100 MOV AL,40
0AF5:0102 MOV BX,1000
0AF5:0105 MOV DS,BX
0AF5:0107 MOV [0],AL
0AF5:010A
-T=100
AX=0040 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0102 NV UP EI PL NZ NA PO NC
0AF5:0102 BB0010 MOV BX,1000
-T
AX=0040 BX=1000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0105 NV UP EI PL NZ NA PO NC
0AF5:0105 8EDB MOV DS,BX
-T
AX=0040 BX=1000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0107 NV UP EI PL NZ NA PO NC
0AF5:0107 A20000 MOV [0000],AL DS:0000=64
-T
AX=0040 BX=1000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=010A NV UP EI PL NZ NA PO NC
0AF5:010A CD21 INT 21
-D 1000:0000 0
1000:0000 40 @
-Q 以上是字节型数据的传送。
字的传送
8086CPU是16位结构,有16根数据线,一次性可以传送16位的数据。
也就是说,可以一次性传送一个字。只要在 mov 指令中给出 16位的寄存器就可以进行16 位数据的传送了。
以下是字的传送练习与内存分析:
0AF5:0100 AX,1000
0AF5:0103 DS,AX
0AF5:0105 MOV AX,[0]
0AF5:0108 MOV BX,[2]
0AF5:010C MOV CX,[1]
0AF5:0110 ADD BX,[1]
0AF5:0114 ADD CX,[2]
0AF5:0118
-T=100
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 8ED8 MOV DS,AX
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0105 NV UP EI PL NZ NA PO NC
0AF5:0105 A10000 MOV AX,[0000] DS:0000=1123
-T
AX=1123 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0108 NV UP EI PL NZ NA PO NC
0AF5:0108 8B1E0200 MOV BX,[0002] DS:0002=6622
-T
AX=1123 BX=6622 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=010C NV UP EI PL NZ NA PO NC
0AF5:010C 8B0E0100 MOV CX,[0001] DS:0001=2211
-T
AX=1123 BX=6622 CX=2211 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0110 NV UP EI PL NZ NA PO NC
0AF5:0110 031E0100 ADD BX,[0001] DS:0001=2211
-T
AX=1123 BX=8833 CX=2211 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0114 OV UP EI NG NZ NA PE NC
0AF5:0114 030E0200 ADD CX,[0002] DS:0002=6622
-T
AX=1123 BX=8833 CX=8833 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0118 OV UP EI NG NZ NA PE NC 寄存器与段间数据传送
0AF5:0100 MOV AX,1000
0AF5:0103 MOV DS,AX
0AF5:0105 MOV [0],CS
0AF5:0109
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC
0AF5:0100 B80010 MOV AX,1000
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 8ED8 MOV DS,AX
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0105 NV UP EI PL NZ NA PO NC
0AF5:0105 8C0E0000 MOV [0000],CS DS:0000=000
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0109 NV UP EI PL NZ NA
-D 1000:0000
1000:0000 [color=Red]F5 0A [/color]00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
-Q “MOV 段寄存器,内存单元” 数据传送分析
Quote: | -d 1000:000
1000:0000 F5 0A 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC
0AF5:0100 B80010 MOV AX,1000
-a
0AF5:0100 MOV AX,1000
0AF5:0103 MOV DS,AX
0AF5:0105 MOV DS,[0]
0AF5:0109
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC
0AF5:0100 B80010 MOV AX,1000
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 8ED8 MOV DS,AX
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1000 ES=0AF5 SS=0AF5 CS=0AF5 IP=0105 NV UP EI PL NZ NA PO NC
0AF5:0105 8E1E0000 MOV DS,[0000] DS:0000=0AF5
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0109 NV UP EI PL NZ NA PO NC |
|
[ Last edited by redtek on 2006-12-21 at 09:33 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-22 04:40 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
53 楼』:
【80x86汇编语言学习笔记】
物理地址 = 段地址*16 + 偏移量
根据上面原理灵活运用计算物理地址的方法,来用不同的段地址与偏移量取“同”一数据:
Quote: | C:\TEMP\debug>DEBUG
-D 0000:0000
0000:0000 68 10 A7 00 8B 01 70 00-16 00 A9 03 8B 01 70 00 h.....p.......p.
0000:0010 8B 01 70 00 B9 06 12 02-40 07 12 02 FF 03 12 02 ..p.....@.......
0000:0020 46 07 12 02 0A 04 12 02-3A 00 A9 03 54 00 A9 03 F.......:...T...
0000:0030 6E 00 A9 03 88 00 A9 03-A2 00 A9 03 FF 03 12 02 n...............
0000:0040 A9 08 12 02 A4 09 12 02-AA 09 12 02 5D 04 12 02 ............]...
0000:0050 B0 09 12 02 0D 02 E1 02-C4 09 12 02 8B 05 12 02 ................
0000:0060 0E 0C 12 02 14 0C 12 02-1F 0C 12 02 AD 06 12 02 ................
0000:0070 AD 06 12 02 A4 F0 00 F0-37 05 12 02 94 2D 00 C0 ........7....-..
变换段地址,取上面红色标注地址:
计算上面红色段地址*16+偏移量 = 物理地址,
然后再将物理地址 / 16 ,偏移量取0000,得到变换地址如下:
-D 0004:0000
0004:0000 A9 08 12 02 A4 09 12 02-AA 09 12 02 5D 04 12 02 ............]...
0004:0010 B0 09 12 02 0D 02 E1 02-C4 09 12 02 8B 05 12 02 ................
0004:0020 0E 0C 12 02 14 0C 12 02-1F 0C 12 02 AD 06 12 02 ................
0004:0030 AD 06 12 02 A4 F0 00 F0-37 05 12 02 94 2D 00 C0 ........7....-..
0004:0040 72 10 A7 00 7C 10 A7 00-4F 03 59 05 8A 03 59 05 r...|...O.Y...Y.
0004:0050 17 03 59 05 86 10 A7 00-90 10 A7 00 9A 10 A7 00 ..Y.............
0004:0060 B8 10 A7 00 54 02 70 00-F2 04 91 D0 B8 10 A7 00 ....T.p.........
0004:0070 B8 10 A7 00 B8 10 A7 00-40 01 27 04 70 09 C8 D8 ........@.'.p...
-D 0005:0000
0005:0000 B0 09 12 02 0D 02 E1 02-C4 09 12 02 8B 05 12 02 ................
0005:0010 0E 0C 12 02 14 0C 12 02-1F 0C 12 02 AD 06 12 02 ................
0005:0020 AD 06 12 02 A4 F0 00 F0-37 05 12 02 94 2D 00 C0 ........7....-..
0005:0030 72 10 A7 00 7C 10 A7 00-4F 03 59 05 8A 03 59 05 r...|...O.Y...Y.
0005:0040 17 03 59 05 86 10 A7 00-90 10 A7 00 9A 10 A7 00 ..Y.............
0005:0050 B8 10 A7 00 54 02 70 00-F2 04 91 D0 B8 10 A7 00 ....T.p.........
0005:0060 B8 10 A7 00 B8 10 A7 00-40 01 27 04 70 09 C8 D8 ........@.'.p...
0005:0070 EA AE 10 A7 00 EE 00 F0-B8 10 A7 00 A6 24 02 CD .............$..
-D 0008:0000
0008:0000 72 10 A7 00 7C 10 A7 00-4F 03 59 05 8A 03 59 05 r...|...O.Y...Y.
0008:0010 17 03 59 05 86 10 A7 00-90 10 A7 00 9A 10 A7 00 ..Y.............
0008:0020 B8 10 A7 00 54 02 70 00-F2 04 91 D0 B8 10 A7 00 ....T.p.........
0008:0030 B8 10 A7 00 B8 10 A7 00-40 01 27 04 70 09 C8 D8 ........@.'.p...
0008:0040 EA AE 10 A7 00 EE 00 F0-B8 10 A7 00 A6 24 02 CD .............$..
0008:0050 B8 10 A7 00 B8 10 A7 00-B8 10 A7 00 B8 10 A7 00 ................
0008:0060 B8 10 A7 00 B8 10 A7 00-B8 10 A7 00 B8 10 A7 00 ................
0008:0070 B8 10 A7 00 B8 10 A7 00-B8 10 A7 00 B8 10 A7 00 ................ |
|
[ Last edited by redtek on 2006-12-21 at 10:01 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-22 10:58 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
54 楼』:
【80x86汇编语言学习笔记】
栈
push ax 的执行由下面两步完成:
1、SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
2、将ax中的内容送入 SS:SP 指向的内存单元处,SS:SP 此时指向新栈顶。
两个寄存器: 段寄存器 SS 和 寄存器 SP,栈顶的段地址存放在 SS 中,偏移地址存放在 SP 中。
任意时刻, SS:SP 指向栈顶元素。
push 和 pop 指令对栈的操作以及为栈设置空间
Quote: | C:\TEMP\debug>DEBUG
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC
0AF5:0100 B80010 MOV AX,1000
-A
0AF5:0100 MOV AX,1000
0AF5:0103 MOV SS,AX
0AF5:0105 MOV SP,0010
0AF5:0108 PUSH AX
0AF5:0109 PUSH BX
0AF5:010A PUSH DS
0AF5:010B
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0100 NV UP EI PL NZ NA PO NC
0AF5:0100 B80010 MOV AX,1000
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=0AF5 CS=0AF5 IP=0103 NV UP EI PL NZ NA PO NC
0AF5:0103 8ED0 MOV SS,AX
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=0010 BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=1000 CS=0AF5 IP=0108 NV UP EI PL NZ NA PO NC
0AF5:0108 50 PUSH AX
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=000E BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=1000 CS=0AF5 IP=0109 NV UP EI PL NZ NA PO NC
0AF5:0109 53 PUSH BX
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=000C BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=1000 CS=0AF5 IP=010A NV UP EI PL NZ NA PO NC
0AF5:010A 1E PUSH DS
-T
AX=1000 BX=0000 CX=0000 DX=0000 SP=000A BP=0000 SI=0000 DI=0000
DS=0AF5 ES=0AF5 SS=1000 CS=0AF5 IP=010B NV UP EI PL NZ NA PO NC |
|
编程:(1)将 10000H ~~ 1000FH 这段空间当作栈,初始状态栈是空的;
(2)设置 AX=001AH,BX=001BH;
(3)将 AX、BX中的数据入栈;
(4)然后将AX、BX清零;
(5)从栈中恢复AX、BX原来的内容。
Quote: | -A
0AF5:0100 MOV AX,1000
0AF5:0103 MOV SS,AX
0AF5:0105 MOV SP,0010
0AF5:0108 MOV AX,001A
0AF5:010B MOV BX,001B
0AF5:010E PUSH AX
0AF5:010F PUSH BX
0AF5:0110 XOR AX,AX
0AF5:0112 XOR BX,BX
0AF5:0114 POP BX
0AF5:0115 POP AX
0AF5:0116 |
|
上面标注绿色的指令是清零指命,利用 XOR 的性质清零,速度快于 MOV AX,0000 ……
MOV AX,0 也可以清零,但其机器码占用了3个字节,如果想让编译出来的程序节省一个字节,则不用这个命令。
经过分析,可以看到下面红色的部分为机器码,占用了3个字节。(能省一个字节就省)
Quote: | 0AF5:0103 B80000 MOV AX,0000 |
|
再看一下SUB (减)指令:
SUB AX,AX 也可以让AX寄存器清零。
下面是 SUB 操作,红色部分是SUB的机器码:
再试验一下 XOR (或)指令:
XOR AX,AX 将 AX 寄存器内容清零
上面的清零的机器码只占用了2个字节。
一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么都不是。
关键在于CPU中寄存器的设置,即: CS IP SS SP DS 的指向。
如果寄存器知识没有学好,很可能往下学习就是寸步难行~:)
[ Last edited by redtek on 2006-12-22 at 04:40 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-22 23:34 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
55 楼』:
现在开始学着写第一个程序~:)
坚持着学就学下来了,越学越难,越难越学。如果没有坚持下来,等于浪费生命~:)
想想阿香婆是怎么熬辣酱的,哈哈……
从刚学到现在,按书上的深度来讲,连入门都没有到~:)
不管,接着往前走~:)
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-23 06:46 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
56 楼』:
【80x86汇编语言学习笔记】
汇编语言程序从写出到最终执行的过程
1) 编写汇编源程序
2) 对源程序进行编译连接
3) 执行
在汇编语言源程序中,包含两种指令: 汇编指令,伪指令。
写第一个代码
Quote: | ;-----------------------------------------
;
; Masm 5.0 1.asm
;
;-----------------------------------------
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 |
|
编译过程:(Masm 5.0)
Quote: | C:\Masm50>masm 1.asm
Invalid keyboard code specified
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
Object filename [1.OBJ]:
Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:
51040 + 450320 Bytes symbol space free
0 Warning Errors
0 Severe Errors
C:\Masm50>type 1.asm|clip
C:\Masm50>link 1
Microsoft (R) Overlay Linker Version 3.60
Copyright (C) Microsoft Corp 1983-1987. All rights reserved.
Run File [1.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
LINK : warning L4021: no stack segment |
|
可执行文件:
Quote: | C:\Masm50>dir 1.*
Volume in drive C is DISK-C
Volume Serial Number is 4089-CA39
Directory of C:\Masm50
2006-12-22 20:48 313 1.asm
2006-12-22 20:50 527 1.EXE
2006-12-22 20:48 66 1.OBJ |
|
跟踪刚才编译的 1.exe 可执行文件过程:
Quote: | AX=0000 BX=0000 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=0000 NV UP EI PL NZ NA PO NC
0B49:0000 B82301 MOV AX,0123
-U
0B49:0000 B82301 MOV AX,0123
0B49:0003 BB5604 MOV BX,0456
0B49:0006 03C3 ADD AX,BX
0B49:0008 03C0 ADD AX,AX
0B49:000A B8004C MOV AX,4C00
0B49:000D CD21 INT 21
0B49:000F 7083 JO FF94
0B49:0011 C406B8C8 LES AX,[C8B8]
0B49:0015 05508D ADD AX,8D50
0B49:0018 46 INC SI
0B49:0019 8050E83E ADC BYTE PTR [BX+SI-18],3E
0B49:001D 0D83C4 OR AX,C483
-R
AX=0000 BX=0000 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=0000 NV UP EI PL NZ NA PO NC
0B49:0000 B82301 MOV AX,0123
-T
AX=0123 BX=0000 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=0003 NV UP EI PL NZ NA PO NC
0B49:0003 BB5604 MOV BX,0456
-T
AX=0123 BX=0456 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=0006 NV UP EI PL NZ NA PO NC
0B49:0006 03C3 ADD AX,BX
-P
AX=0579 BX=0456 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=0008 NV UP EI PL NZ NA PO NC
0B49:0008 03C0 ADD AX,AX
-P
AX=0AF2 BX=0456 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=000A NV UP EI PL NZ AC PO NC
0B49:000A B8004C MOV AX,4C00
-P
AX=4C00 BX=0456 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=000D NV UP EI PL NZ AC PO NC
0B49:000D CD21 INT 21
-P
Program terminated normally
-Q |
|
头晕,PSP……
操作系统的外壳……
程序是如何执行的?
1) 在DOS中直接执行 1.exe 时,是正在运行的 command ,将 1.exe 中的程序加载入内存;
2) command 设置 CPU 的 CS:IP 指向程序的第一条指令(即程序的入口),从而使程序得以运行;
3) 程序运行结束后,返回到 command 中, CPU 继续运行 command。
可执行程序被加载的过程:
1) 找到一段起始地址 SA:0000 的容量足够的空闲内存;
2) 在这段内存区的前 256 个字节中,创建一个称为程序段前缀(PSP)的数据区,DOS要利用PSP来和被加载程序进行通信;
---------内存---------
////////
////////
sa: ------------------------
PSP
------------------------ SA + 10H:0
CS:IP
程
序
------------------------
3) 从这段内存区的 256 字节处开始(在PSP的后面),将程序装入。
程序的地址被设为 SA + 10H : 0 ;
空闲的内存区从 SA:0 开始, 0~~255 字节为 PSP,从 256 字节处开始存放程序。
为更好地区分 PSP 和程序,DOS一般将它们划分到不同的段中,所以有这样的地址安排:
空闲内存区: SA : 0
PSP区: SA : 0
程序区: SA + 10H : 0
注意: PSP区和程序区虽然物理地址连续,却有不同的段地址。
4) 将该内存区的段地址存入 DS 中,初始化其他相关寄存器后,设置 CS:IP 指向程序入口。
PSP 占 256(100H)字节,所以程序的物理地址是:SA*16+0+256=SA*16+16*16+0=(SA+16)*16+0
可用段地址和偏移地址表示为:SA+10:0。
理解:设 DS=129E ,问 PSP 地址? 和程序的地址是多少?
程序加载后,DS中存放着程序所在的内存区的段地址,这个内存区的偏移地址为0,则程序所在的内存区的地址为 DS:0
程序地址: 129E*16+0+256=129E0+100H=12AE0H(物理地址)=12AE:0=CS:0(相对地址)
PSP 地址: 129E:0
但是,上面求程序所在地址(非物理地址)可以如下变通:
求物理地址: 129E*16相当于(129E0),而加256相当于(加100H),
129E0H
100H
--------------------- +
12AE0H 但求 段:偏移量 地址方式,则还要再去一个0(相当于除16),所以应如下变通:
129EH + 10H = 12AE:0000 这样就求出了: 段地址:偏移量
上面就是程序是如何分配程序地址的计算原理的过程~:)
怎么可以“直观”的看到PSP的“标置”?PSP的头两个字节是 CD 20
Quote: | C:\Masm50>DEBUG 1.EXE
-R
AX=0000 BX=0000 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B49 IP=0000 NV UP EI PL NZ NA PO NC
0B49:0000 B82301 MOV AX,0123
-D DS:0000
0B39:0000 CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 59 05 8A 03 . ........O.Y...
0B39:0010 59 05 17 03 59 05 48 05-01 01 01 00 02 FF FF FF Y...Y.H.........
0B39:0020 FF FF FF FF FF FF FF FF-FF FF FF FF 06 0B 4C 01 ..............L.
0B39:0030 19 0A 14 00 18 00 39 0B-FF FF FF FF 00 00 00 00 ......9.........
0B39:0040 05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0B39:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!...........
0B39:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 .....
0B39:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
-Q |
|
编译成 .exe 文件,用 Debug 调试代码
Quote: | ASSUME CS:CODESG
CODESG SEGMENT
MOV AX,2000H
MOV SS,AX
MOV SP,0
ADD SP,4
POP AX
POP BX
PUSH AX
PUSH BX
POP AX
POP BX
MOV AX,4C00H
INT 21H
CODESG ENDS
END |
|
因为栈空间分配大小的原因,编译成 .exe 文件后在 MS-DOS 6.22 下调试正常,在Windows CMD 内调试出错,增加栈空间即可。
[ Last edited by redtek on 2006-12-23 at 09:05 AM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-23 08:08 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
57 楼』:
【80x86汇编语言学习笔记】
汇编指令描述方式
内存单元的描述
mov ax,[0]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为0,段地址在ds中。
描述练习
1) ax中的内容为0010H,描述它
(ax)=0010H
2) 2000:1000 处的内容为 0010H
(21000H)= 0010H
3) mov ax,[2]
(ax)= ((ds)* 16 + 2)
4) mov [2],ax
((ds)* 16 + 2)= (ax)
5) add ax,2
(ax)=(ax)+ 2
6) add ax,bx
(ax)=(ax)+(bx)
7) push ax
(sp)=(sp)- 2
((ss)* 16 + (sp))= (ax)
8) pop ax
(ax)=((ss)* 16 + (sp))
(sp)=(sp)+ 2
为什么要这样描述?
这种描述方式可以更深的理解指令的物理内存操作原理和所有过程,它是理解更多内容与原理的必须基础。
[ Last edited by redtek on 2006-12-23 at 10:06 AM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-23 22:44 |
|
|
ccwan
金牌会员
积分 2725
发帖 1160
注册 2006-9-23 来自 河北廊坊
状态 离线
|
『第
58 楼』:
redtek笔耕不辍,我来鼓励一下!
|
三人行,必有吾师焉。 学然后知不足,教然后知困,然后能自强也。 |
|
2006-12-24 00:10 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
59 楼』:
多谢ccwan兄不断鼓励~:)
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-24 01:58 |
|
|
redtek
金牌会员
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第
60 楼』:
【80x86汇编语言学习笔记】
循环指令与编译器
下面代码 Masm 5.0 编译通过~:)
Quote: | ;------------------------------------------------
; 计算 2的2次方
;-------------------------------------------------
ASSUME CS:CODE
CODE SEGMENT
MOV AX,2
ADD AX,AX
MOV AX,4C00H
INT 21H
CODE ENDS
END |
|
但是,如果要使用 ADD 指令计算几好百个次方,是不是要输出几百个指令?
可以用 Loop 循环指令模拟一下,这东东稍微有点儿像批处理里的 Goto 语句,哈哈……
先一步一步慢慢来,先分析上面代码编译之后的样子~:)
象 “ASSUME CS:CODE” 与 “CODE SEGMENT” 等都是汇编伪指令,CPU不认识,它由 Masm 编译器编译时“转化”。
Quote: | C:\Masm50>debug LOOP.EXE
-r
AX=0000 BX=0000 CX=000A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3C ES=0B3C SS=0B4C CS=0B4C IP=0000 NV UP EI PL NZ NA PO NC
0B4C:0000 B80200 MOV AX,0002
-t
AX=0002 BX=0000 CX=000A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3C ES=0B3C SS=0B4C CS=0B4C IP=0003 NV UP EI PL NZ NA PO NC
0B4C:0003 03C0 ADD AX,AX
-t
AX=0004 BX=0000 CX=000A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3C ES=0B3C SS=0B4C CS=0B4C IP=0005 NV UP EI PL NZ NA PO NC
0B4C:0005 B8004C MOV AX,4C00
-t
AX=4C00 BX=0000 CX=000A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3C ES=0B3C SS=0B4C CS=0B4C IP=0008 NV UP EI PL NZ NA PO NC
0B4C:0008 CD21 INT 21
-p
Program terminated normally
-q |
|
下面使用循环计算2的12次方
Quote: | ;----------------------------------------
; 2 ^ 12 次方计算
;----------------------------------------
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 |
|
Loop 是循环,S:是循环标号, mov cx,11 ,每次循环一次cx寄存器值被递减。
执行顺序:执行到 Loop 时,CX值先减1,然后如果判断不为0,则跳转到标号。
它是如何跳转到标号的?它会修改 IP 的指向,cpu 执行 CS:IP 所指向的指令,然自就“返回”了标号处。
在Debug中跟踪Loop指令
Quote: | C:\Masm50>debug loop12.exe
-r
AX=0000 BX=0000 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3D ES=0B3D SS=0B4D CS=0B4D IP=0000 NV UP EI PL NZ NA PO NC
0B4D:0000 B80200 MOV AX,0002
-u cs:0 D
0B4D:0000 B80200 MOV AX,0002
0B4D:0003 B90B00 MOV CX,000B
0B4D:0006 03C0 ADD AX,AX
0B4D:0008 E2FC LOOP 0006
0B4D:000A B8004C MOV AX,4C00
0B4D:000D CD21 INT 21-R
AX=0000 BX=0000 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3D ES=0B3D SS=0B4D CS=0B4D IP=0000 NV UP EI PL NZ NA PO NC
0B4D:0000 B80200 MOV AX,0002
-T
AX=0002 BX=0000 CX=000F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3D ES=0B3D SS=0B4D CS=0B4D IP=0003 NV UP EI PL NZ NA PO NC
0B4D:0003 B90B00 MOV CX,000B
-T
AX=0002 BX=0000 CX=000B DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3D ES=0B3D SS=0B4D CS=0B4D IP=0006 NV UP EI PL NZ NA PO NC
0B4D:0006 03C0 ADD AX,AX
-T
AX=0004 BX=0000 CX=000B DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3D ES=0B3D SS=0B4D CS=0B4D IP=0008 NV UP EI PL NZ NA PO NC
0B4D:0008 E2FC LOOP 0006
-T
AX=0004 BX=0000 CX=000A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3D ES=0B3D SS=0B4D CS=0B4D IP=0006 NV UP EI PL NZ NA PO NC
0B4D:0006 03C0 ADD AX,AX |
|
上面代码中的棕色代码与汇编源代码中的伪指令的区别。
绿色代码为执行Loop时的跳转与 IP 的指向。
看循环指令结果时,也可以使用 Debug P 指令来跟踪最后的结果。
下面是计算 123 * 236
Quote: | ;------------------------------------------------
;
; 123 * 236
;
;------------------------------------------------
assume cs:code
code segment
mov ax,0
mov cx,123
s: add ax,236
loop s
mov ax,4c00h
int 21h
code ends
end |
|
如果下面这样写结果也一样正确:
mov cx,236
s: add ax,123
但,相当于循环了 236 遍,如果 mov cx,123 ,则相当于只循环了123遍,速度稍快一些。
在Debug中跟踪下面编译的代码
Quote: | assume cs:code
code segment
mov ax,0ffffh
mov ds,ax
mov bx,6
mov al,[bx] ; 以上,设置(al)=((ds*16)+(bx)), (ah)=0
mov ah,0
mov dx,0 ; 累加寄存器清0
mov cx,3 ; 循环3次
s: add dx,ax ; 以上累加计算(ax)*3
loop s
mov ax,4c00h
int 21h
code ends
end |
|
可以看到,Loop指令的每一步是如何工作的……
Quote: | AX=0034 BX=0006 CX=0003 DX=0034 SP=0000 BP=0000 SI=0000 DI=0000
DS=FFFF ES=0B3D SS=0B4D CS=0B4D IP=0014 NV UP EI PL NZ NA PO NC
0B4D:0014 E2FC LOOP 0012
-t
(当上面这句 Loop 0012 执行时,寄存器状态如下面所示)
AX=0034 BX=0006 CX=0002 DX=0034 SP=0000 BP=0000 SI=0000 DI=0000
DS=FFFF ES=0B3D SS=0B4D CS=0B4D IP=0012 NV UP EI PL NZ NA PO NC
0B4D:0012 03D0 ADD DX,AX
-t
(上面是到了标号处的指令)
AX=0034 BX=0006 CX=0002 DX=0068 SP=0000 BP=0000 SI=0000 DI=0000
DS=FFFF ES=0B3D SS=0B4D CS=0B4D IP=0014 NV UP EI PL NZ NA PO NC
0B4D:0014 E2FC LOOP 0012
-t
AX=0034 BX=0006 CX=0001 DX=0068 SP=0000 BP=0000 SI=0000 DI=0000
DS=FFFF ES=0B3D SS=0B4D CS=0B4D IP=0012 NV UP EI PL NZ NA PO NC
0B4D:0012 03D0 ADD DX,AX
-t
AX=0034 BX=0006 CX=0001 DX=009C SP=0000 BP=0000 SI=0000 DI=0000
DS=FFFF ES=0B3D SS=0B4D CS=0B4D IP=0014 NV UP EI PL NZ NA PE NC
0B4D:0014 E2FC LOOP 0012
-t |
|
如果(cx)=(cx)-1 ,当(cx)=0时: 因为(cx)=0,Loop指令不跳转。向下执行。
[ Last edited by redtek on 2006-12-23 at 05:27 PM ]
|
Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-12-24 02:16 |
|
|