我一直关注this tutorial,以了解如何检查和启用A20线。我想我理解了,但是有人可以帮我澄清一下吗?
该教程中已有的注释以; <comment>
开始,
我的评论开始;<comment>
; The following code is public domain licensed
[bits 16]
; Function: check_a20
;
; Purpose: to check the status of the a20 line in a completely self-contained state-preserving way.
; The function can be modified as necessary by removing push's at the beginning and their
; respective pop's at the end if complete self-containment is not required.
;
; Returns: 0 in ax if the a20 line is disabled (memory wraps around)
; 1 in ax if the a20 line is enabled (memory does not wrap around)
check_a20:
pushf ;Backup the current flags onto the stack
;Backup the below registers onto the stack
push ds ;|
push es ;|
push di ;|
push si ;-----
cli ;Disable interupts
xor ax, ax ; ax = 0
mov es, ax ;es = ax
not ax ; ax = 0xFFFF
mov ds, ax ; ds = ax
mov di, 0x0500 ;Boot signature part one (0x55)
mov si, 0x0510 ;Boot signature part two (0xAA)
mov al, byte [es:di] ;al = value at AA:55
push ax ;Backup ax register onto the stack
mov al, byte [ds:si] ;al = value at 55:AA
push ax ;Backup al onto the stack
mov byte [es:di], 0x00 ;Memory location AA:55 = 0
mov byte [ds:si], 0xFF ;Memory location at 55:AA = 0xFF
cmp byte [es:di], 0xFF ;Does value at AA:55 = 0xFF? If so, this means A20 is disabled
pop ax ;Restore saved ax register
mov byte [ds:si], al ;Set 55:AA to al
pop ax ;Restore ax register
mov byte [es:di], al ;set AA:55 to al
mov ax, 0 ;Return status of this function = 0 (Disabled)
je check_a20__exit ;A20 is disabled. Go to check_a20__exit
mov ax, 1 ;Return status of this function = 1 (Enabled)
check_a20__exit:
;Backup registers
pop si
pop di
pop es
pop ds
popf ;Backup flags
ret ;Return
如果我不理解某些部分,请解释一下原因吗?
答案 0 :(得分:4)
代码正在通过写入两者来检查FFFF:0510
和0000:0500
是否引用相同的地址,并查看写入一个地址是否覆盖另一个地址。
事实证明,FFFF:0510
可以代表线性地址0x100500
而不是0x500
,但前提是启用了A20。因此,代码会将所有零写入es:di
(又名0000:0500
)的字节,并将所有零写入ds:si
(又名FFFF:0510
)的字节。如果启用了A20,则两个segment:offset对将引用不同的地址,第一次写入将保持不变,并且[es:di]
将包含零。否则,这两对将指向同一地址,第二对写入将破坏第一个,而[es:di]
将包含0xff
。
(顺便说一下,0x55
和0xAA
并不是其中的一部分;我不确定您从何处获得这些数字。引导签名通常位于0x7dfe,即IIRC。)< / p>
答案 1 :(得分:2)
我认为您错过了Wiki中的这一行:
以下代码执行检查(与上述操作不同-更直接)。
如果禁用了A20,则这两个位置互为别名。如果没有,他们就不会。这就是为什么它会存储两个不同的值,然后检查其中有什么。 (第二商店是否具有别名。)
如果您要在高地址处检查0xAA55签名,则只能进行加载。另外,即使在规范化之后,地址(FFFF:0500
和0000:0510
)也不等于0000:7DFE
(引导扇区签名的位置)和FFFF:7E0E
(可能是别名)。
您是凭空补足了AA和55的;它们不会出现在代码中的任何地方,并且从您找到它们的地址开始没有负载。