【发布时间】:2021-10-04 16:17:07
【问题描述】:
您好,这个问题一直在我不断出现的笑脸。我的工作涉及 2 个文件。
第一个是后台引导加载程序,里面的所有东西都很好用,没有改变,但第二个文件支持成为一个 hello world,但只会产生重复出现的笑脸。
program_space equ 0x7e00 ; program space variable equates to 0x7e00.
; 0x7e00 is 512 bytes after 0x7c00 in memory
[org 0x7c00] ; declares the origin at the location 0x7c00
; disk number is stored in al register
mov bp, 0x7c00 ; moves 0x7c00 to the base pointer, CS:IP
; CS:IP always points to physical address 0x07C00.
mov sp, bp ; moves the base pointer bp to the stack pointer sp
; the basic_input_output_system(bios) automatically stores the disk number that the program was loaded from into the dl register
mov [boot_disk], dl ; moves dl contents to boot disk
mov al, [program_space] ; moves the program space to al
mov ah, 0x0e ; BIOS.Teletype
mov al, '1' ; Moves '1' to al register
int 0x10 ; calls print
mov al, ' ' ; Moves ' ' to al register
int 0x10 ; calls print
mov bx, Hello_World ; move Hello_World labels position to bx[16 bit]
call print_string ; calls print_string function
mov ah, 0x0e ; BIOS.Teletype
mov al, 0xa ; move down 1 line.
int 0x10 ; print al
mov al, 0xd ; move position to start of line.
int 0x10 ; print al
call read_disk ; calls read_disk function position
mov bx, disk_read_true ; moves disk_read_true to bx register
call print_string ; calls print_string function
jmp program_space ; jumps to program_space
jmp $ ; declares an infinite loop
print_string: ; declares the label location of print_string function
push ax ; pushes the ax register
push bx ; pushes the bx register
mov ah, 0x0e ; BIOS.Teletype
.loop: ; declares the label location of loop
cmp [bx], byte 0 ; compares a size of 0 bytes to bx register
je .exit ; if equal jump to .exit label
mov al, [bx] ; moves bx contents to al register
int 0x10 ; declares print
inc bx ; increment the bx register
jmp .loop ; jump to .loop to create a for loop
.exit: ; declares the label location of exit
pop ax ; pops the ax register
pop bx ; pops the bx register
ret ; returns to position to call print_string
read_disk: ; declares read_disk position
mov ah, 0x02 ; moves bios read sectors into memory to ah
mov bx, program_space ; moves the program space to bx
mov al, 4 ; reads 4 sectors aka 2000 bytes, or 2 kilobytes
mov dl, [boot_disk] ; moves the value of boot disk into dl
mov ch, 0x00 ; moves cyclinder 0 of hard drive into ch
mov dh, 0x00 ; moves cyclinder 0 of hard drive into dh
mov cl, 0x02 ; Moves 2 cylinders to cl
int 0x13 ; interrupt commands the bios to read the disk
jc disk_read_false ; jumps conditionaly to disk read false
ret ; returns from read_disk to its call
disk_read_false: ; declares the disk_read_false location
mov bx, disk_read_error ; moves the disk read error label to bx register
call print_string ; declares a call to the print_string function
jmp $ ; declares infinite loop
Hello_World: db 'Hello World!',0 ; declares the hello World position and the string Hello World!
disk_read_error: db 'Disk Read = False;',0 ; declares disk_read_error position
disk_read_true: db 'Disk Read = True;',0 ; declares the disk_read_true position
boot_disk: db 0 ; declares boot_disk position defines a bite of 0
times 510-($-$$) db 0 ; fills the drive with 510 bytes of ($-$$).
; each ($-$$) is a double byte of 0.
; that makes up 510/512 bytes for the bootloader
dw 0xaa55 ; declares a bootloader using a double word occupying 2/512 bytes
; total is 512/512 bytes = 2/512 bytes + 510/512 bytes
这是下面有问题的文件
; Ralf Brown's Interrupt List
[org 0x7e00] ; program space variable equates to 0x7e00.
; 0x7e00 is 512 bytes after 0x7c00 in memory
mov ah, 0x0e ; BIOS.Teletype
mov al, 0xa ; **move down 1 line.**
int 0x10 ; **declares print**
mov al, 0xd ; **move position to start of line.**
int 0x10 ; **declares print**
mov bx, extended_space_true
call print_string
jmp activate_protected_mode
activate_protected_mode:
call activate_A20
cli
lgdt [g.d.t_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp codeseg:protected_mode_start
activate_A20:
in al, 0x92
or al, 2
out 0x92, al
ret
[bits 32]
protected_mode_start:
mov ax, dataseg
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 90000
mov esp, ebp
mov [0xb8000], byte 'H'
mov [0xb8002], byte 'e'
mov [0xb8004], byte 'l'
mov [0xb8006], byte 'l'
mov [0xb8008], byte 'o'
mov [0xb800a], byte ' '
mov [0xb800c], byte 'W'
mov [0xb800e], byte 'o'
mov [0xb8010], byte 'r'
mov [0xb8012], byte 'l'
mov [0xb8014], byte 'd'
mov [0xb8016], byte '!'
jmp $
g.d.t.asm:
g.d.t_null_descriptor:
dd 0
dd 0
g.d.t_code_descriptor: ; **declares g.d.t_code_descriptor location**
dw 0xffff ; **limit**
dw 0x0000 ; **limit base(low)**
db 0x00 ; **Base (medium)**
db 10011010b ; **flags**
db 11001111b ; **flags + upper limit**
db 0x00 ; **base (high)**
g.d.t_data_descriptor: ; **declares g.d.t_data_descriptor location**
dw 0xffff ; **limit**
dw 0x0000 ; **limit base(low)**
db 0x00 ; **Base (medium)**
db 10010010b ; **flags**
db 11001111b ; **flags + upper limit**
db 0x00 ; **base (high)**
g.d.t_end:
g.d.t_descriptor:
g.d.t_size:
dw g.d.t_end - g.d.t_null_descriptor - 1
dd g.d.t_null_descriptor
codeseg equ g.d.t_code_descriptor - g.d.t_null_descriptor
dataseg equ g.d.t_data_descriptor - g.d.t_null_descriptor
print_string: ; **declares position of print_string function**
push ax ; **pushes the ax register**
push bx ; **pushes the bx register**
mov ah, 0x0e ; **BIOS.Teletype**
.loop: ; **declares position of loop**
cmp [bx], byte 0 ; **compares a size of 0 bytes to bx**
je .exit ; **if the result is equal jump to exit**
mov al, [bx] ; **declares move value at bx to al.**
int 0x10 ; **declares print**
inc bx ; **increment the bx as a for loop**
jmp .loop ; **jump to the for loop**
.exit: ; **labels position of exit**
pop ax ; **pops the ax register**
pop bx ; **pops the bx register**
ret **; returns to position of call printstring**
extended_space_true: db 'Extended Space = True;',0
times 2048-($-$$) db 0
我对代码的解释在旁边
【问题讨论】:
-
请参观而不是垃圾邮件 30 次“请帮助我”这只是粗鲁,不会增加您得到任何答案的概率
-
正如@Björn 指出的那样,请查看tour,并查看how to ask a good question 上的部分。
标签: assembly nasm x86-16 bootloader