Почему я возвращаю 32 вместо 64 в защищенном режиме для IN AL, DX с порта ввода-вывода 0x1F7? - PullRequest
0 голосов
/ 04 марта 2020

Я хочу отправлять команды на жесткий диск. Я осознаю, что жесткий диск должен быть готов к приему и отправке команд. Для следующего фрагмента кода, почему все возвращает 32 вместо 64 в защищенном режиме?

        ;no drive commands were executed before this code
        mov dx,0x1F7
drive_loop:
        in al, dx       ;port input, result saved in al
        bt eax, 7       ;checks if BSY is set
        jc drive_loop   ;jumps back if BSY is set
        inc al          ;checks if the answer is 32 by forcing it to display ! through incrementing al
        mov [0xb8000], al
        dec al
        jmp $           ;al contains 32

Для минимально воспроизводимого примера
Загрузить: http://diamondmenmaster.com/Reproducible/Reproducible.zip
Полный код:

[org 0x7c00]
stack:
; Setup the stack away from our code.
not bp; Set the stack base (bottom)
mov sp, bp ; Set the stack top to the base (i.e. an empty stack)
init_pm:
cli;disables interrupts
lgdt [gdt_descriptor];setup the user data for protected mode
mov eax, cr0;moves cr0 register to the eax register
inc eax;increases the eax register by 1
mov cr0, eax;moves eax register to the cr0 register
mov ax, DATA_SEG;moves DATA_SEG to the eax register
;sets ax register to ds,ss,es,fs,gs registers
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000;Updates the stack position so it is right
mov esp, ebp;at the top of the free space.
jmp 08h:BEGIN_PM;starts protected mode with code starting at BEGIN_PM

[bits 32]

BEGIN_PM :
mov al,0x11;initialization sequence
out 0x20,al;sends ax register to 8259A-1
out 0xA0,al;and to 8259A-2
mov al,0x20;sets up the start of hardware interrupts (0x20)
out 0x21,al
mov al,0x28;sets up the start of hardware interrupts 2 (0x28)
out 0xA1,al
mov al,0x04;8259-1 is master
out 0x21,al
mov al,0x02; 8259-2 is slave
out 0xA1,al
mov al,0x01;8086 mode for both
out 0x21,al
out 0xA1,al
interrupt_setup:
mov eax,[idt_start];moves half of the interrupt descriptor for a interrupt to the eax register
mov edx,[idt_start + 4];moves the other half of the interrupt descriptor to the edx register

mov ecx,0x20*8;moves the location of the interrupt descriptor for the timer device to the ecx register
mov [ecx],eax;moves eax register to the location stored in the ecx register
;increments ecx by 1 by four times
inc ecx
inc ecx
inc ecx
inc ecx
mov [ecx],edx;moves edx register to the location stored in the ecx register

mov ecx,0x21*8;moves the location of the interrupt descriptor for the keyboard device to the ecx register
mov ax,Key_Handler;moves the location of Keyboard interrupt handler to the ecx register
mov [ecx],eax;moves eax register to the location stored in the ecx register
;increments ecx by 1 by four times
inc ecx
inc ecx
inc ecx
inc ecx
mov [ecx],edx;moves edx register to the location stored in the ecx register
sti;enables interrupts

repeat:
hlt;waits for any device interrupts
jmp repeat;jumps back to wait again

Interput_Handler:;handles the timer interrupts
mov al,0x20
out 0x20,al;lets devices know that the os is ready to receive another interrupt
iret;returns from the interrupt routine

Key_Handler:;handles the keyboard interrupts
        ;no drive commands were executed before this code
        mov dx,0x1F7
drive_loop:
        in al, dx       ;port input, result saved in al
        bt eax, 7       ;checks if BSY is set
        jc drive_loop   ;jumps back if BSY is set
        inc al          ;checks if the answer is 32 by forcing it to display ! through incrementing al
        mov [0xb8000], al
        dec al
        jmp $           ;al contains 32
mov al,0x20
out 0x20,al;lets devices know that the os is ready to receive another interrupt
iret;returns from the interrupt routine

Data:

idt_start:
dw Interput_Handler
dw CODE_SEG
db 0x0
db 0b11101111
dw 0x00

gdt_start:
gdt_null: ; the mandatory null descriptor
dd 0x0
dd 0x0
gdt_code: ; the code segment descriptor
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0

gdt_data: ; the data segment descriptor
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:

gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

; Pad out the boot sector to 512 bytes with last 2 bytes as verification number.
times 510-($-$$) db 0
dw 0xaa55
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...