Правильно ли я понимаю код проверки линии A20? - PullRequest
0 голосов
/ 05 октября 2018

Я следовал этому уроку о том, как проверить и включить линию 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

Если я не понимаю некоторые разделы, не могли бы вы объяснить, почему?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Я думаю, что вы пропустили эту строку в вики:

Следующий код выполняет проверку (не так, как описано выше - более прямо).

Если A20отключено, эти два местоположения псевдоним друг друга.Если нет, то нет.Вот почему он делает два хранилища разных значений, а затем проверяет, что там.(Независимо от того, во 2-ом хранилище или нет.)

Если бы вы проверяли подпись 0xAA55 по старому адресу, вы бы выполняли только загрузки.Кроме того, адреса (FFFF:0500 и 0000:0510) не равны 0000:7DFE (расположение подписи загрузочного сектора) и FFFF:7E0E (возможно, псевдонимы) даже после нормализации.

Youсоставляли АА и 55 из воздуха;они нигде не присутствуют в коде, и они не загружаются с адреса, по которому вы их найдете.

0 голосов
/ 05 октября 2018

Код проверяет, ссылаются ли FFFF:0510 и 0000:0500 на один и тот же адрес, записывая оба и проверяя, перезаписывает ли один адрес другой.

Как выясняется, FFFF:0510 можетпредставляет линейный адрес 0x100500, а не 0x500, но только если A20 включен.Таким образом, код записывает все нули в байт на es:di (он же 0000:0500), а все нули в байт на ds:si (он же FFFF:0510).Если A20 активирован, то две пары сегмент: смещение относятся к разным адресам, первая запись будет выполняться, а [es:di] будет содержать ноль.В противном случае две пары ссылаются на один и тот же адрес, вторая запись закроет первую, а [es:di] будет содержать 0xff.

(Кстати, 0x55 и 0xAA не являютсячасть этого; я не уверен, откуда вы взяли эти числа. Подпись загрузки обычно на 0x7dfe, IIRC.)

...