中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » 网络日志(Blog) » 【Redtek】 个人网志(学习笔记)
« [1] [2] [3] [4] [5] [6] [7] [8] [9] »
作者:
标题: 【Redtek】 个人网志(学习笔记) 上一主题 | 下一主题
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的机器码:

  Quote:
0AF5:0103 29C0          SUB     AX,AX

再试验一下 XOR (或)指令:

XOR  AX,AX   将 AX 寄存器内容清零

  Quote:
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) 执行




在汇编语言源程序中,包含两种指令: 
汇编指令伪指令


写第一个代码

  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
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] [3] [4] [5] [6] [7] [8] [9] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: