鱼C论坛

 找回密码
 立即注册
查看: 2687|回复: 0

[学习笔记] 和CPU说话05

[复制链接]
发表于 2017-7-8 16:23:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
2017.7.8
断断续续看了几天书,收获不多,脑子里翻来覆去就是自己的系统到底该怎么做。
MLGB的,MS-DOS1.0版本,1981年8月发布,仅支持单面软盘。它到底是怎么做到的?
哪里能找到这东西的解剖版啊,我好想弄明白怎么不用int 13 控制软驱...
前段时间逐条注释int 13,这几天也暂停了,工作量太大了,未知的东西也太多了,今天发一段代码上来,万一哪个有空的兄弟帮提点一下也能省我好多功夫。

文件中0000EC5B处应该是int 13的入口
实模式下内存F000:0000~F000:FFFF 反汇编代码:
文件附后。

我自己的注释也发一发,虽然还没完成,虽然可能仅仅是起了个头:
  1.         ;Int 13h
  2.        
  3.         jmp a
  4. a:
  5.         cmp ah,0x4a
  6.         jc b                        ;CF进位时跳转(意思是小于4a跳转?)
  7.         cmp ah,0x4d
  8.         ja b                        ;无符号大于跳转
  9.         pushaw                        ;将8个通用寄存器入栈
  10.         push es
  11.         push ds
  12.     push cs
  13.         pop ds                        ;ds=cs
  14.         cld                                ;正向?
  15.         push word 0xece9;这里暂且不用管他的具体数值,因为读写磁盘不用到这里
  16.         jmp word 0x3c0c        ;

  17. b:
  18.         push es                        ;读写软盘时跳到这里
  19.         push ax
  20.         push bx
  21.         push cx
  22.         push dx
  23.         call onecall        ;第一CALL
  24.         cmp al,0x0                ;al=[es:336h]=[[word 0040:000e]:336h] 查证后 al=0
  25.         jz c                        ;好像是为0跳转
  26.        
  27.         call twocall        ;******这里应该暂时不用管 因为 还没有到这里******
  28.        
  29.        
  30. c:                                        ;第一CALL   al=[9fc0:336h]=[9ff3:6]=0后跳到这里 等于前边什么都没做
  31.                                         ;[9ff3:6] 在 EBDA(Extended BIOS Data Area)扩展BIOS数据区
  32.         pop dx
  33.         pop cx
  34.         pop bx
  35.         pop ax
  36.         pop es
  37.         push ax
  38.         push cx
  39.         push dx                        ;
  40.         push bx
  41.         push dx
  42.         push bp
  43.         push si
  44.         push di
  45.         push es                        ;bp+6
  46.         push ds                        ;bp+4
  47.         push cs                        ;这两步是设置DS=CS
  48.         pop ds
  49.         cld
  50.         test dl,0x80        ;TEST dl,bl 与 AND dl,bl 差不多,根据结果设置标志寄存器,结果本身不会保存
  51.         ;这里应该是判断是选择什么驱动器的,因为80~ff是硬盘 80h 的2进制是 1000 0000
  52.         jnz 0xecc8                ;这里的意思是大于80h 就跳转暂时我不读写硬盘,先不管跳哪
  53.         push word 0xece9;bp+2
  54.         jmp word 0x3288        ;我们如果读写软盘,就会从这里起跳
  55.        
  56. d:
  57.         push bp
  58.         mov bp,sp
  59.         push si
  60.         push di
  61.         sub sp,byte +0x16        ;这里是啥意思啊? 栈指针减16h(22),留出22个内存?
  62.         mov bx,[bp+0x16]        ;bx=ax这是什么意思?好像这个内存值是ax的值
  63.         shr bx,0x8                        ;bl=ah假如是ax值 ,那么这里就是取aH的值,int13入口 哈哈
  64.         mov [bp-0x8],bl                ;入口值ah存入 [ss:bp-8]
  65.         mov si,[bp+0x16]        ;si=ax
  66.         and si,0xff                        ;si低位清零
  67.         mov al,[bp+0xe]                ;al=dl 但是这里不太清楚是高位还是低位***???应该是低位
  68.         mov ah,[bp+0x14]        ;ah=cl
  69.         mov cl,[bp+0x16]        ;cl=al
  70.         mov dx,[bp+0x14]        ;dx=cx
  71.         shr dx,0x8                        ;dl=ch
  72.         mov [bp-0x12],dx        ;cx存入 [ss:bp-0x12]
  73.         cmp bl,0x8                        ;将入口值ah与8比
  74.         jc e                                ;借位时跳转  读写都是小于8 所以这里跳转
  75.        
  76. e:
  77.         cmp bl,0x1
  78.         jc 0x3309                        ;小于1跳转? 很明显读写值大于1,所以暂且不管他
  79.         jna word 0x3382                ;无符号不大于跳转,意思是小于等于跳转,暂且不管他
  80.         cmp bl,0x5
  81.         jz word 0x36cc                ;等于5时跳转,还是不管他
  82.         cmp bl,0x4
  83.         jna word f                        ;无符号不大于跳转,意思是小于等于跳转,啊哈哈 是他是他就是他
  84.        
  85. f:
  86.         mov ch,cl                        ;ch=al(入口值,要读写的扇区数)
  87.         mov dl,[bp-0x12]        ;dl=cl(入口值,起始扇区号)
  88.         mov [bp-0xa],dl                ;cl(入口值,起始扇区号)存入[bp-0xa]
  89.         mov [bp-0x6],ah                ;cl(入口值,起始扇区号)存入[bp-0x6]
  90.         mov dx,[bp+0x12]        ;dx=dx(入口值,
  91.         shr dx,0x8                        ;dl=dh(入口值,磁头号)
  92.         mov [bp-0xe],dl                ;dh(入口值,磁头号)存入[bp-0xe]
  93.         mov [bp-0xc],al                ;dl(入口值,驱动器号)存入[bp-0xc]
  94.         cmp al,0x1                        ;此时al=入口的dl值驱动器号*****??????????
  95.         ja 0x33c9                        ;无符号大于1跳转,我用1号软驱读写,不管他
  96.         cmp dl,0x1                        ;此时dl=磁头号 也就是入口时的dh,与1比
  97.         ja 0x33c9                        ;大于跳,我应该只读写两面,也就是0~1,所以这个不管他
  98.         test cl,cl                        ;测试要读写的扇区数
  99.         jz 0x33c9                        ;为0跳,我要读写肯定不为0,所以不管他
  100.         cmp cl,0x48                        ;测试要读写的扇区数是否大于48h
  101.         jna g;0x33f3                ;小于等于就跳 就跳
  102.        
  103. g:
  104.         movzx ax,[bp-0xc]        ;高位扩展为0 即 ax=0000+dl(dl为入口值)
  105.         call gcall                        ;word 0x3264  应该快接近真相了吧
  106.         test ax,ax                        ;ax=1或者0,这是从71h端口读出的一个数值处理后得到
  107.         jz word 0x3500                ;为0时跳,***暂时先不理会***
  108.         ;假设ax=1,执行下列命令
  109.         movzx dx,[bp-0xc]        ;高位扩展为0 即 dx=0000+dl(dl为入口值)
  110.         mov ax,dx                        ;ax=dl(dl为入口值)
  111.         call g2call                        ;word 0x30a9
  112.         test ax,ax
  113.        
  114.        
  115.        
  116.        
  117. g2call:
  118.         push bp
  119.         mov bp,sp
  120.         push bx
  121.         push dx
  122.         mov bx,ax                        ;bx=dl(dl为入口值)
  123.         mov dx,0x3e
  124.         mov ax,0x40
  125.         call onecalltwo                ;word 0x16b8        又去查bios数据区;
  126.         ;40:003e表示磁盘驱动器的搜索状态。
  127.         ;如果这些位中有一位为0,则表示在搜索磁道之前,必须重新校准相应的驱动器。
  128.         ;位4-6未使用,位7为中断标志位,为1表示中断发生
  129.         ;BIOS数据区说明 https://wenku.baidu.com/view/5c865a2aeff9aef8941e06d8.html
  130.         mov ah,al                        ;ah=al=多少呢? 暂时先不理会***
  131.         test bx,bx                        ;bx=dl(dl为入口值)
  132.         jz 0x30c1                        ;dl不为0,不跳
  133.         shr al,1                        ;因为不是0号驱动器,所以al右移1位?
  134.         and al,0x1                        ;保留1号驱动的搜索状态
  135.         jnz Ncalibration        ;0x30c9        ;看是否需要重新校准? 不为0则跳,为0则往下执行校准
  136.         xor ah,ah
  137.         jmp short 0x30e5
  138.        
  139. Ncalibration:
  140.         mov dx,0x90                        ;dx上一步值为0x3e,再上一步dx=0000+dl(dl为入口值)
  141.         test bx,bx                        ;bx=dl(dl为入口值)
  142.         jz 0x30d3                        ;dl不为0,不跳
  143.         mov dx,0x91
  144.         mov ax,0x40
  145.         call onecalltwo                ;word 0x16b8        又去查bios数据区;
  146.         ;40:0091 字节 驱动器1介质状态
  147.         xor ah,ah
  148.         sar ax,0x4                        ;SAR是算术右移指令,功能是将操作数右移,符号位保持不变
  149.         ;作用是将AX中的数右移4位,这样就是取al的高4位
  150.         ;第4位 介质已知 5 需要双倍速率  
  151.         ;第6~7位  磁盘数据传送速率  00:500K/S    01:300K/S 10:250K/S    11:保留
  152.         ;https://wenku.baidu.com/view/9ba4d2f5ba0d4a7302763a48.html
  153.         and al,0x1                        ;此意是查介质是否已知,但是不知道是0为已知还是1为已知
  154.         jz 0x30c5                        ;介质是否已知,反正为0跳转,跳了以后会xor ah,ah 然后接下下步
  155.         mov ax,0x1
  156.         lea sp,[bp-0x4]                ;介质是否已知,都会跳到这里,不同的是ax=0或者1,到这里我有点接不下去了
  157.         pop dx
  158.         pop bx
  159.         pop bp
  160.         ret                                        ;g2call的 ret
  161.         ;好想放弃了,2万行左右的代码,我这里只看了200来行,花了十来天了
  162.         ;查不到的东西越来越多,好难啊。。。到底该从哪学??
  163.        
  164. gcall:
  165.         push bp
  166.         mov bp,sp
  167.         push dx                                ;dx=00dh,入栈(入口值,磁头号)
  168.         mov dx,ax                        ;dx=00dl,(入口值,驱动器号) 操他妈的换来换去有意思?
  169.         mov ax,0x10                        ;ax=0x10
  170.         call gcallcall                ;word 0x1714        ;
  171.         test dx,dx                        ;dx还是=00dl (入口值,驱动器号)
  172.         jnz port70                        ;0x3279                ;我要写的是1号软驱,所以这里不为0,跳
  173.         shr al,0x4                        ;dl不为0,到不了这一步 上一步就ret了
  174.         jmp short 0x327b

  175.        
  176. port70:
  177.         and al,0xf                        ;将al高4位置0
  178.         test al,al                        ;
  179.         setnz al                        ;Sets the byte in the operand to 1 if the Zero Flag is clear
  180.         ;otherwise sets the operand to 0
  181.         ;如果ZF标志位为0,al=1 如果ZF标志位为1,al=0
  182.         xor ah,ah                        ;ah=0
  183.         lea sp,[bp-0x2]                ;例行放屁
  184.         pop dx
  185.         pop bp
  186.         ret                                        ;gcall完结点,返回g
  187.        
  188. gcallcall:       
  189.         push bp
  190.         mov bp,sp
  191.         push dx                                ;dx=00dl,入栈(入口值,驱动器号)
  192.         mov ah,0x70                        ;ax=0x7010
  193.         cmp al,0x80                        ;al=0x10,和0x80比
  194.         jc here                                ;0x1720                        ;借位跳转,这里是跳的
  195.         mov ah,0x72
  196. here:                                        ;第一次端口读写操作
  197.         movzx dx,ah                        ;高位扩展为0,即 dx=00ah=0x0070
  198.         out dx,al                        ;给70h端口赋值 0x10 ****** 此端口写入数据后不知道会发生什么
  199.         ;70h端口好像是CMOS的端口,给这个端口写入"9,8,7,4,2,0"分别是读年月日,时秒分进71h端口
  200.         ;这里到底是不是CMOS的端口呢??
  201.         ;写入0x10 即从0x10处读取数值,这个数值是什么?就不知道是什么意思了
  202.         ;CMOSRAM 内容:https://wenku.baidu.com/view/de597a671ed9ad51f01df274.html?re=view
  203.         ;Bits 7-4 = Drive 0 type
  204.         ;Bits 3-0 = Drive 1 type  
  205.         movzx dx,ah                        ;高位扩展为0,即 dx=00ah=0x0070
  206.         inc dx                                ;dx=0x0071
  207.         in al,dx                        ;读取71h端口一个数进al
  208.         sub ah,ah                        ;ah=0
  209.         lea sp,[bp-0x2]                ;这是在脱裤子放屁吗,lea指令将一个近地址指针写入到指定的寄存器
  210.         ;这里即将ss:[bp-2]的地址赋值给sp,而sp的值本来就是这个嘛
  211.         pop dx                                ;dx=00dl(入口值,驱动器号)
  212.         pop bp
  213.         ret                                 ;gcallcall 的 ret
  214.        
  215.        
  216.        
  217.        
  218.        
  219.        
  220. onecall:       
  221.         push bp                        ;保存bp
  222.         mov bp,sp                ;bp=sp   等于栈指针此时的数值,6 这之前push了6个寄存器,最后一个是bp
  223.         mov dx,0xe
  224.         mov ax,0x40
  225.         call onecallone
  226.         mov dx,0x366
  227.         call onecalltwo
  228.         mov sp,bp
  229.         pop bp
  230.         ret
  231.        
  232. onecallone:                        ;此时dx=0xe  ax=0x40
  233.                                         ;bios数据查询程序,这里查字 单元
  234.         push bx                       
  235.         push bp                       
  236.         mov bp,sp                ;等于栈指针此时的数值,6 这之前push了8个寄存器,最后一个是bp
  237.         mov bx,dx
  238.         mov es,ax
  239.         mov ax,[es:bx]        ;ax=[0040:000e] 这里是BIOS数据区的一个数值,不知道是什么
  240.         pop bp
  241.         pop bx
  242.         ret
  243. onecalltwo:                        ;此时dx=0x366 ax=[0040:000e]=9fc0
  244.                                         ;第二次dx=0x3e ax=0x40
  245.                                         ;bios数据查询程序,这里查字节 单元
  246.         push bx
  247.         push bp
  248.         mov bp,sp
  249.         mov bx,dx
  250.         mov es,ax                ;es=[0040:000e]=9fc0       
  251.         mov al,[es:bx]        ;al=[9fc0:336h]=[9ff3:6]=0
  252.         pop bp
  253.         pop bx
  254.         ret
  255.        
  256. twocall:       
  257.         push bp
  258.         mov bp,sp
  259.         mov dx,0xe
  260.         mov ax,0x40
  261.         call onecallone
  262.         mov dx,0x368
  263.         call onecalltwo
  264.         mov sp,bp       
  265.         pop bp
  266.         ret

复制代码

2017.7.8

F0000~FFFFF.rar

128.19 KB, 下载次数: 1

实模式下F0000~FFFFF

评分

参与人数 1鱼币 +6 收起 理由
小甲鱼 + 6

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-24 00:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表