鱼C论坛

 找回密码
 立即注册
查看: 1695|回复: 6

[技术交流] 01. 人工反编译 - bootsect.s

[复制链接]
发表于 2020-5-4 17:20:59 | 显示全部楼层 |阅读模式

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

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

x
最近在学习linux 0.11源代码,bootsect.s 文件中有一个 read_it 函数,用来读取软盘上的system模块
这个函数是这个文件中最复杂的一个,相信不少同学被这个函数劝退,我也被劝退n次
这一次我使用人工反编译,把汇编语言翻译成语义上等效的C语言代码
这一次我终于理解了这个函数的逻辑,把自己的翻译结果发上来,希望可以帮到更多的同学,^_^


这个代码可以编译运行,如果有不理解的地方,还可以调试运行这个程序
  1. #define SETUPLEN 4
  2. #define SYSSIZE  0x3000
  3. #define SYSSEG   0x1000
  4. #define ENDSEG   (SYSSEG + SYSSIZE)

  5. const int sectors = 18;
  6. int sread = 1 + SETUPLEN;
  7. int head  = 0;
  8. int track = 0;

  9. void read_track(int count) {
  10.     (void)count;
  11. }

  12. void read_it(int es) {
  13.     while(es & 0x0fff)
  14.         ;
  15.    
  16.     int offset = 0;
  17.     while(1) {
  18.         if(es >= ENDSEG)
  19.             return;
  20.         
  21.         int count = sectors - sread;
  22.         if(count * 512 + offset > 0x10000)
  23.             count = (0x10000 - offset) / 512;
  24.         read_track(count);
  25.         
  26.         int sum = sread + count;
  27.         if(sum == sectors) {
  28.             if(head == 1) {
  29.                 head = 0; ++track;
  30.             }
  31.             else ++head;
  32.             sum = 0;
  33.         }
  34.         
  35.         sread = sum;
  36.         offset += count * 512;
  37.         if(offset < 0x10000)
  38.             continue;
  39.         es += 0x1000;
  40.         offset = 0;
  41.     }
  42. }

  43. int main(void) {
  44.     read_it(SYSSEG);
  45.     return 0;
  46. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-5-4 17:22:22 | 显示全部楼层
本帖最后由 人造人 于 2020-5-4 17:34 编辑

把 bootsect.s 也贴上来吧
  1. !
  2. ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
  3. ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
  4. ! versions of linux
  5. !
  6. SYSSIZE = 0x3000
  7. !
  8. !       bootsect.s              (C) 1991 Linus Torvalds
  9. !
  10. ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
  11. ! iself out of the way to address 0x90000, and jumps there.
  12. !
  13. ! It then loads 'setup' directly after itself (0x90200), and the system
  14. ! at 0x10000, using BIOS interrupts.
  15. !
  16. ! NOTE! currently system is at most 8*65536 bytes long. This should be no
  17. ! problem, even in the future. I want to keep it simple. This 512 kB
  18. ! kernel size should be enough, especially as this doesn't contain the
  19. ! buffer cache as in minix
  20. !
  21. ! The loader has been made as simple as possible, and continuos
  22. ! read errors will result in a unbreakable loop. Reboot by hand. It
  23. ! loads pretty fast by getting whole sectors at a time whenever possible.

  24. .globl begtext, begdata, begbss, endtext, enddata, endbss
  25. .text
  26. begtext:
  27. .data
  28. begdata:
  29. .bss
  30. begbss:
  31. .text

  32. SETUPLEN = 4                            ! nr of setup-sectors
  33. BOOTSEG  = 0x07c0                       ! original address of boot-sector
  34. INITSEG  = 0x9000                       ! we move boot here - out of the way
  35. SETUPSEG = 0x9020                       ! setup starts here
  36. SYSSEG   = 0x1000                       ! system loaded at 0x10000 (65536).
  37. ENDSEG   = SYSSEG + SYSSIZE             ! where to stop loading

  38. ! ROOT_DEV:     0x000 - same type of floppy as boot.
  39. !               0x301 - first partition on first drive etc
  40. ROOT_DEV = 0x306

  41. entry start
  42. start:
  43.         mov     ax,#BOOTSEG
  44.         mov     ds,ax
  45.         mov     ax,#INITSEG
  46.         mov     es,ax
  47.         mov     cx,#256
  48.         sub     si,si
  49.         sub     di,di
  50.         rep
  51.         movw
  52.         jmpi    go,INITSEG
  53. go:     mov     ax,cs
  54.         mov     ds,ax
  55.         mov     es,ax
  56. ! put stack at 0x9ff00.
  57.         mov     ss,ax
  58.         mov     sp,#0xFF00              ! arbitrary value >>512

  59. ! load the setup-sectors directly after the bootblock.
  60. ! Note that 'es' is already set up.

  61. load_setup:
  62.         mov     dx,#0x0000              ! drive 0, head 0
  63.         mov     cx,#0x0002              ! sector 2, track 0
  64.         mov     bx,#0x0200              ! address = 512, in INITSEG
  65.         mov     ax,#0x0200+SETUPLEN     ! service 2, nr of sectors
  66.         int     0x13                    ! read it
  67.         jnc     ok_load_setup           ! ok - continue
  68.         mov     dx,#0x0000
  69.         mov     ax,#0x0000              ! reset the diskette
  70.         int     0x13
  71.         j       load_setup

  72. ok_load_setup:

  73. ! Get disk drive parameters, specifically nr of sectors/track

  74.         mov     dl,#0x00
  75.         mov     ax,#0x0800              ! AH=8 is get drive parameters
  76.         int     0x13
  77.         mov     ch,#0x00
  78.         seg cs
  79.         mov     sectors,cx
  80.         mov     ax,#INITSEG
  81.         mov     es,ax

  82. ! Print some inane message

  83.         mov     ah,#0x03                ! read cursor pos
  84.         xor     bh,bh
  85.         int     0x10
  86.         
  87.         mov     cx,#24
  88.         mov     bx,#0x0007              ! page 0, attribute 7 (normal)
  89.         mov     bp,#msg1
  90.         mov     ax,#0x1301              ! write string, move cursor
  91.         int     0x10

  92. ! ok, we've written the message, now
  93. ! we want to load the system (at 0x10000)

  94.         mov     ax,#SYSSEG
  95.         mov     es,ax           ! segment of 0x010000
  96.         call    read_it
  97.         call    kill_motor

  98. ! After that we check which root-device to use. If the device is
  99. ! defined (!= 0), nothing is done and the given device is used.
  100. ! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
  101. ! on the number of sectors that the BIOS reports currently.

  102.         seg cs
  103.         mov     ax,root_dev
  104.         cmp     ax,#0
  105.         jne     root_defined
  106.         seg cs
  107.         mov     bx,sectors
  108.         mov     ax,#0x0208              ! /dev/ps0 - 1.2Mb
  109.         cmp     bx,#15
  110.         je      root_defined
  111.         mov     ax,#0x021c              ! /dev/PS0 - 1.44Mb
  112.         cmp     bx,#18
  113.         je      root_defined
  114. undef_root:
  115.         jmp undef_root
  116. root_defined:
  117.         seg cs
  118.         mov     root_dev,ax

  119. ! after that (everyting loaded), we jump to
  120. ! the setup-routine loaded directly after
  121. ! the bootblock:

  122.         jmpi    0,SETUPSEG

  123. ! This routine loads the system at address 0x10000, making sure
  124. ! no 64kB boundaries are crossed. We try to load it as fast as
  125. ! possible, loading whole tracks whenever we can.
  126. !
  127. ! in:   es - starting address segment (normally 0x1000)
  128. !
  129. sread:  .word 1+SETUPLEN        ! sectors read of current track
  130. head:   .word 0                 ! current head
  131. track:  .word 0                 ! current track

  132. read_it:
  133.         mov ax,es
  134.         test ax,#0x0fff
  135. die:    jne die                 ! es must be at 64kB boundary
  136.         xor bx,bx               ! bx is starting address within segment
  137. rp_read:
  138.         mov ax,es
  139.         cmp ax,#ENDSEG          ! have we loaded all yet?
  140.         jb ok1_read
  141.         ret
  142. ok1_read:
  143.         seg cs
  144.         mov ax,sectors
  145.         sub ax,sread
  146.         mov cx,ax
  147.         shl cx,#9
  148.         add cx,bx
  149.         jnc ok2_read
  150.         je ok2_read
  151.         xor ax,ax
  152.         sub ax,bx
  153.         shr ax,#9
  154. ok2_read:
  155.         call read_track
  156.         mov cx,ax
  157.         add ax,sread
  158.         seg cs
  159.         cmp ax,sectors
  160.         jne ok3_read
  161.         mov ax,#1
  162.         sub ax,head
  163.         jne ok4_read
  164.         inc track
  165. ok4_read:
  166.         mov head,ax
  167.         xor ax,ax
  168. ok3_read:
  169.         mov sread,ax
  170.         shl cx,#9
  171.         add bx,cx
  172.         jnc rp_read
  173.         mov ax,es
  174.         add ax,#0x1000
  175.         mov es,ax
  176.         xor bx,bx
  177.         jmp rp_read

  178. read_track:
  179.         push ax
  180.         push bx
  181.         push cx
  182.         push dx
  183.         mov dx,track
  184.         mov cx,sread
  185.         inc cx
  186.         mov ch,dl
  187.         mov dx,head
  188.         mov dh,dl
  189.         mov dl,#0
  190.         and dx,#0x0100
  191.         mov ah,#2
  192.         int 0x13
  193.         jc bad_rt
  194.         pop dx
  195.         pop cx
  196.         pop bx
  197.         pop ax
  198.         ret
  199. bad_rt: mov ax,#0
  200.         mov dx,#0
  201.         int 0x13
  202.         pop dx
  203.         pop cx
  204.         pop bx
  205.         pop ax
  206.         jmp read_track

  207. /*
  208. * This procedure turns off the floppy drive motor, so
  209. * that we enter the kernel in a known state, and
  210. * don't have to worry about it later.
  211. */
  212. kill_motor:
  213.         push dx
  214.         mov dx,#0x3f2
  215.         mov al,#0
  216.         outb
  217.         pop dx
  218.         ret

  219. sectors:
  220.         .word 0

  221. msg1:
  222.         .byte 13,10
  223.         .ascii "Loading system ..."
  224.         .byte 13,10,13,10

  225. .org 508
  226. root_dev:
  227.         .word ROOT_DEV
  228. boot_flag:
  229.         .word 0xAA55

  230. .text
  231. endtext:
  232. .data
  233. enddata:
  234. .bss
  235. endbss:
复制代码

评分

参与人数 1鱼币 +2 收起 理由
Hello. + 2 鱼C有你更精彩^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-5-4 17:24:10 | 显示全部楼层
初学C语言表示瑟瑟发抖
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 17:25:59 | 显示全部楼层
十分有用!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-4 17:27:04 | 显示全部楼层
老八秘制 发表于 2020-5-4 17:24
初学C语言表示瑟瑟发抖

^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 17:50:38 | 显示全部楼层
没学c语言表示瑟瑟发抖

即将被Hello.攻破电脑表示瑟瑟发抖
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-4 17:54:05 | 显示全部楼层
乘号 发表于 2020-5-4 17:50
没学c语言表示瑟瑟发抖

即将被Hello.攻破电脑表示瑟瑟发抖

C语言不难,真的,^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-12 15:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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