我是汇编新手,我正在以引导加载程序的形式编写一个小型汇编程序。但是,当我添加更多变量时,它将减少我的变量。怎么了?该程序似乎已耗尽“空间”。它是第二阶段的引导程序,因此第一部分将加载实际程序。第二阶段是否受到大小限制?
一切正常,直到我检查了一定数量的代码。
这是第一阶段的引导程序:
[org 0x7c00]
[bits 16]
pre:
cmp ah, 0x0F ; checking if coming from other app or first load - setting ah to 0F before jmping back to the bootloader
je welcome
mov [bootdev], dl ; Save boot device number
jmp welcome
welcome:
xor ax,ax ; We want a segment of 0 for DS for this question
mov ds,ax ; Set AX to appropriate segment value for your situation
mov es,ax ; In this case we'll default to ES=DS
mov bx,0x8000 ; Stack segment can be any usable memory
mov ss,bx ; This places it with the top of the stack @ 0x80000.
mov sp,ax ; Set SP=0 so the bottom of stack will be @ 0x8FFFF
cld ; Set the direction flag to be positive direction
mov ah, 01h ;make cursor invisible
mov cx, 2607h
int 10h
mov ah, 06h ; Set overall background
xor al, al ; and clear entire screen
xor cx, cx ; Upper left corner CH=row, CL=column = 0
mov dx, 184Fh ; lower right corner DH=row, DL=column = 25 x 80 / textmode
mov bh, 1Eh ; YellowOnBlue
int 10h
mov ah, 06h; top bar, make background
xor cx, cx
mov dx, 0x004F
mov bh, 30h
int 10h
mov ah, 02h ;top bar setting the position and then write title to it
mov bh, 0h
mov dh, 0h
mov dl, 20h
int 10h
mov si, title
call wolf_print
mov ah, 02h ;sets cursor to top to write
mov bh, 0h
mov dh, 2h
mov dl, 1h
int 10h
mov si, wolf_wel_msg
call wolf_print
mov si, xpub
call wolf_print
start:
mov ah, 0x00
int 0x16
jmp load_it_all_1
load_it_all_1:
mov si, wolf_kernel_load
call wolf_print
pushf
stc
mov ah,00
int 13h
.read_sector:
mov ax, 0x0
mov es, ax ; ES = 0
mov bx, 0x1000 ; BX = 0x1000. ES:BX=0x0:0x1000
; ES:BX = starting address to read sector(s) into
mov ah, 02 ; Int 13h/AH=2 = Read Sectors From Drive
mov al, 01 ; Sectors to read = 1
mov ch, 00 ; CH=Cylinder. Second sector of disk
; is at Cylinder 0 not 1
mov cl, 02 ; Sector to read = 2
mov dh, 00 ; Head to read = 0
; DL hasn't been destroyed by our bootloader code and still
; contains boot drive # passed to our bootloader by the BIOS
mov dl, [bootdev]
int 13h
jc wolf_error
popf
jmp 0x0:0x1000
cli
hlt
wolf_error:
mov si, wolf_error_msg
call wolf_print
mov si, wolf_error_msg1
call wolf_print
mov ah,00
int 16h
xor ax,ax
int 19h
wolf_print:
lodsb
or al,al
jz exit
mov ah,0x0e
int 10h
jmp wolf_print
exit:
ret
over:
jmp start
; Moved the data before the boot signature but after the code
wolf_wel_msg db 'Welcome to this publication..., press a key to ENTER',0x0D,0x0A,0
wolf_kernel_load db 'Loading program',0x0D,0x0A,0
wolf_error_msg db 'Program not found!',0x0D,0x0A,0
wolf_error_msg1 db 'Press any key to restart..',0
xpub db "WELCOME", 0
title db 'NOT MY DEFAULT',0
bootdev db 0x80 ; Boot device number
times 510-($-$$) db 0
dw 0xAA55
这是问题所在的第二阶段:
[org 0x1000]
global start
section .text
start:
mov ah, 01h ;make cursor invisible
mov cx, 2607h
int 10h
mov ah, 06h ; Scroll up function
xor al, al ; Clear entire screen
xor cx, cx ; Upper left corner CH=row, CL=column
mov dx, 184FH ; lower right corner DH=row, DL=column
mov bh, 1Eh ; YellowOnBlue
int 10H ; execute interrupt
mov ah, 06h ;draw rect on background
mov cx, 0101h
mov dx, 124Dh
mov bh, 3Eh
int 10h
mov ah, 06h ;draw shadow
mov cx, 1302h
mov dx, 134Eh
mov bh, 0Eh
int 10h
mov ah, 06h ;draw shadow
mov cx, 024Eh
mov dx, 134Eh
mov bh, 0Eh
int 10h
; menu bottom
mov ah, 06h ;draw rect on background
mov cx, 1700h
mov dx, 184Fh
mov bh, 3Fh
int 10h
mov ah, 02h ;sets cursor to top to write
mov bh, 0h
mov dh, 17h
mov dl, 2h
int 10h
mov si, menuhelp
call print
mov si, menuselect
call print
mov si, menuexit
call print
mov ah, 02h ;sets cursor to top to write
mov bh, 0h
mov dh, 4h
mov dl, 4h
int 10h
mov si, msg1
call print
print_projects:
mov ah, 02h ;sets cursor to top to write
mov bh, 0h
mov dh, 6h ;row
mov dl, 4h ;col
int 10h
xor bx, bx ; Starting at offset zero
lea di, [projects] ; RDI now has the address of the array
.loop
mov [storebx], bx
mov ah, 02h
;mov bh, 0h
add dh, 1h ;move cursor down
mov dl, 4h;
int 10h
mov ax, [currentselection]
cmp ax, bx
jne .normalbackground
mov ah, 06h ;draw rect on background
mov ch, dh
mov cl, 4h
mov dl, 24h
mov bh, 7Ch
int 10h
jmp .drawstring
.normalbackground
mov ah, 06h ;draw rect on background
mov ch, dh
mov cl, 4h
mov dl, 24h
mov bh, 1Eh
int 10h
jmp .drawstring
.drawstring
mov bx, [storebx]
mov si, [di+bx] ; Get the address of string1
call print
add bx, 8
cmp bx, 48
jne .loop
jmp waitforkey
waitforkey:
mov ah, 0x00
int 0x16
cmp ah, 1Fh
je .up
cmp ah, 11h
je .down
jmp waitforkey
.up
mov ax, [currentselection]
cmp ax, 40
je .reup
add ax, 8
mov [currentselection], ax
jmp print_projects
.reup
mov ax, 0
mov [currentselection], ax
jmp print_projects
.down
mov ax, [currentselection]
cmp ax, 0
je .redown
sub ax, 8
mov [currentselection], ax
jmp print_projects
.redown
mov ax, 40
mov [currentselection], ax
jmp print_projects
print:
lodsb
or al,al
jz exit
mov ah,0x0e
int 10h
jmp print
exit:
ret
section .data
msg1 db "ARTIST / TITLE",0
project1 db "Name / Exampletitle of this",0
project2 db "Name2 / Silence and more",0
project3 db "Name3 / C00l", 0
project4 db "Name4 / Everyon", 0
project5 db "Name5 / Voices and more", 0
project6 db "Name6 / Examples of titles", 0
projects dq project1, project2, project3, project4, project5, project6
menuhelp db "F1 Help", 0
menuselect db " W/S Select Item",0
menuexit db 0x0D,0x0A," ESC Exit", 0
currentselection dw 0
storebx dw 0
我用
编译nasm -f bin -o boot.bin boot.asm
nasm -f bin -o program.bin program.asm
并使用
创建可引导映像sudo dd if=/dev/zero of=disk.img bs=1024 count=720
sudo dd if=boot.bin of=disk.img bs=512 count=1 conv=notrunc
sudo dd if=program.bin of=disk.img bs=512 seek=1 count=1 conv=notrunc
(然后我正在使用qemu-system-x86_64 disk.img进行测试)
答案 0 :(得分:0)
我解决了! 因此,确实如@prl所指出的,需要交换要读取的扇区数。
.read_sector:
mov ax, 0x0
mov es, ax ; ES = 0
mov bx, 0x1000 ; BX = 0x1000. ES:BX=0x0:0x1000
; ES:BX = starting address to read sector(s) into
mov ah, 02 ; Int 13h/AH=2 = Read Sectors From Drive
mov al, 02 ; Sectors to read, depends on how big the second program / kernel is
mov ch, 00 ; CH=Cylinder. Second sector of disk
; is at Cylinder 0 not 1
mov cl, 02 ; Sector to read = 2
mov dh, 00 ; Head to read = 0
此外,还需要更改图像的创建。 (请参阅将计数更改为2),这意味着它将每个512字节的2个sektor写入.img。
sudo dd if=/dev/zero of=disk.img bs=1024 count=720
sudo dd if=boot.bin of=disk.img bs=512 count=1 conv=notrunc
sudo dd if=program.bin of=disk.img bs=512 seek=1 count=2 conv=notrunc