|
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汇编语言学习笔记】
寄存器汇编指令练习: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汇编语言学习笔记】
程序段中指令执行练习:-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: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操作如下: -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 段寄存器,内存单元” 数据传送分析-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 + 偏移量
根据上面原理灵活运用计算物理地址的方法,来用不同的段地址与偏移量取“同”一数据: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 指令对栈的操作以及为栈设置空间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原来的内容。-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个字节。(能省一个字节就省) 0AF5:0103 B80000 MOV AX,0000 再看一下SUB (减)指令:
SUB AX,AX 也可以让AX寄存器清零。
下面是 SUB 操作,红色部分是SUB的机器码: 0AF5:0103 29C0 SUB AX,AX 再试验一下 XOR (或)指令:
XOR AX,AX 将 AX 寄存器内容清零 0AF5:0103 31C0 XOR 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) 执行
在汇编语言源程序中,包含两种指令: 汇编指令, 伪指令。
写第一个代码;-----------------------------------------
;
; 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)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 可执行文件: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 可执行文件过程: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 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 调试代码 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 编译通过~:) ;------------------------------------------------
; 计算 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 编译器编译时“转化”。 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次方;----------------------------------------
; 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指令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 ;------------------------------------------------
;
; 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中跟踪下面编译的代码 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指令的每一步是如何工作的……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 |
|
|