Assembly 引导加载程序加载映像文件
我需要一些帮助来理解用BrokenThorn的引导加载程序加载内核的逻辑 守则:Assembly 引导加载程序加载映像文件,assembly,bootloader,Assembly,Bootloader,我需要一些帮助来理解用BrokenThorn的引导加载程序加载内核的逻辑 守则: LOAD_IMAGE: mov ax, WORD [cluster] ; cluster to read pop bx ; buffer to read into call ClusterLBA
LOAD_IMAGE:
mov ax, WORD [cluster] ; cluster to read
pop bx ; buffer to read into
call ClusterLBA ; convert cluster to LBA
;xor cx, cx
;mov cl, BYTE [bpbSectorsPerCluster] ; sectors to read (commenting out has same result?
call ReadSectors ;(ES:BX from above)
push bx
; compute next cluster
mov ax, WORD [cluster] ; identify current cluster
mov cx, ax ; copy current cluster
mov dx, ax ; copy current cluster
shr dx, 0x0001 ; divide by two
add cx, dx ; sum for (3/2)
mov bx, 0x0200 ; location of FAT in memory
add bx, cx ; index into FAT
mov dx, WORD [bx] ; read two bytes from FAT
test ax, 0x0001
jnz .ODD_CLUSTER
.EVEN_CLUSTER:
and dx, 0000111111111111b ; take low twelve bits
jmp .DONE
.ODD_CLUSTER:
shr dx, 0x0004 ; take high twelve bits
.DONE:
mov WORD [cluster], dx ; store new cluster
cmp dx, 0x0FF0 ; test for end of file
jb LOAD_IMAGE
DONE:
mov si, msgCRLF
call Print
push WORD 0x0050
push WORD 0x0000
retf
为什么我需要将CHS转换为LBA?在函数中,LBA似乎存储在AX寄存器中。但是它没有被用于读取扇区
?然后,将当前集群复制到AX中
ClusterLBA:
sub ax, 0x0002 ; zero base cluster number
xor cx, cx
mov cl, BYTE [bpbSectorsPerCluster] ; convert byte to word
mul cx
add ax, WORD [datasector] ; base data sector
ret
此外,引导加载程序将内核加载到内存位置0x0050:0x0000
为什么我不能jmp 0x0050:0x0000
并开始执行代码?什么是
推送字0x0050
推送字0x0000
是吗?教程中没有对此进行解释 ClusterLBA将群集(在AX中)转换为扇区(在AX中),以便能够通过int 13h读取这些扇区。
ReadSectors似乎将AX、ES:BX作为参数。
Push,Push,retf相当于jmp-far。两个变体都有5个字节长。没有区别。ClusterLBA将群集(AX中)转换为扇区(AX中),以便能够通过int 13h读取这些扇区。
ReadSectors似乎将AX、ES:BX作为参数。
Push,Push,retf相当于jmp-far。两个变体都有5个字节长。没有区别。ClusterLBA将群集(AX中)转换为扇区(AX中),以便能够通过int 13h读取这些扇区。
ReadSectors似乎将AX、ES:BX作为参数。
Push,Push,retf相当于jmp-far。两个变体都有5个字节长。没有区别。ClusterLBA将群集(AX中)转换为扇区(AX中),以便能够通过int 13h读取这些扇区。
ReadSectors似乎将AX、ES:BX作为参数。
Push,Push,retf相当于jmp-far。两个变体都有5个字节长。没有区别。为什么我需要将CHS转换为LBA? 你没有,代码在我能看到的任何地方都没有这样做。我假设代码所做的是将(FAT)“集群号”转换为LBA号。请注意,FAT文件系统使用集群(可能是512字节,1024字节,…),其中集群编号与分区的开始(而不是磁盘的开始)相关 在函数中,LBA似乎存储在AX寄存器中。但它没有在ReadSector中使用? 您没有发布
ReadSectors
的代码,也没有提供指向该代码所在位置的链接。我只能假设您错了,ReadSectors
确实在AX中使用了LBA(例如,在使用int0x13
加载扇区之前,立即进行LBA到CHS的快速转换)
为什么我不能jmp 0x0050:0x0000并开始执行代码?
你可以
遗憾的是,许多编写汇编语言代码的人不是汇编语言程序员(例如,他们可能是懂一点汇编语言的C程序员)。更可悲的是,一些顽固的老装配工不是很好,让人们很难想出如何跳远。基本上,“push;push;retf”之所以存在,是因为编写它的人没有或无法找到正确的方法。为什么我需要将CHS转换为LBA? 你没有,代码在我能看到的任何地方都没有这样做。我假设代码所做的是将(FAT)“集群号”转换为LBA号。请注意,FAT文件系统使用集群(可能是512字节,1024字节,…),其中集群编号与分区的开始(而不是磁盘的开始)相关 在函数中,LBA似乎存储在AX寄存器中。但它没有在ReadSector中使用? 您没有发布
ReadSectors
的代码,也没有提供指向该代码所在位置的链接。我只能假设您错了,ReadSectors
确实在AX中使用了LBA(例如,在使用int0x13
加载扇区之前,立即进行LBA到CHS的快速转换)
为什么我不能jmp 0x0050:0x0000并开始执行代码?
你可以
遗憾的是,许多编写汇编语言代码的人不是汇编语言程序员(例如,他们可能是懂一点汇编语言的C程序员)。更可悲的是,一些顽固的老装配工不是很好,让人们很难想出如何跳远。基本上,“push;push;retf”之所以存在,是因为编写它的人没有或无法找到正确的方法。为什么我需要将CHS转换为LBA? 你没有,代码在我能看到的任何地方都没有这样做。我假设代码所做的是将(FAT)“集群号”转换为LBA号。请注意,FAT文件系统使用集群(可能是512字节,1024字节,…),其中集群编号与分区的开始(而不是磁盘的开始)相关 在函数中,LBA似乎存储在AX寄存器中。但它没有在ReadSector中使用? 您没有发布
ReadSectors
的代码,也没有提供指向该代码所在位置的链接。我只能假设您错了,ReadSectors
确实在AX中使用了LBA(例如,在使用int0x13
加载扇区之前,立即进行LBA到CHS的快速转换)
为什么我不能jmp 0x0050:0x0000并开始执行代码?
你可以
遗憾的是,许多编写汇编语言代码的人不是汇编语言程序员(例如,他们可能是懂一点汇编语言的C程序员)。更可悲的是,一些顽固的老装配工不是很好,让人们很难想出如何跳远。基本上,“push;push;retf”之所以存在,是因为编写它的人没有或无法找到正确的方法。为什么我需要将CHS转换为LBA? 你没有,代码在我能看到的任何地方都没有这样做。我假设代码是做什么的