汇编会切断变量,导致内存不足?

时间:2019-04-23 07:34:00

标签: assembly memory bootloader

我是汇编新手,我正在以引导加载程序的形式编写一个小型汇编程序。但是,当我添加更多变量时,它将减少我的变量。怎么了?该程序似乎已耗尽“空间”。它是第二阶段的引导程序,因此第一部分将加载实际程序。第二阶段是否受到大小限制?

一切正常,直到我检查了一定数量的代码。

这是第一阶段的引导程序:

[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进行测试)

1 个答案:

答案 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