-2

I have some problems... about making a bootloader. I'm a little bit unsure if this is a 32-bit assembly but if you see there it's 16-bit...

Here's my code: (fortr_foload.asm)

[ bits 16 ]
[ org 0x7c00 ]

bootstart:
    xor ax,ax
    mov bx,ax
    mov cx,ax
    mov dx,ax
    mov es,ax

    mov ax,0x8000

    mov si,fortr_loadbOutp
    call fortr_outpf
    
    fortr_loadbOutp db 'booted!!!'

fortr_outpf:
    mov ah,0x0E
    %include "fortr_kernel.asm"
    call fortrk_start
.repboot_fortr:
    lodsb
    cmp al,0
    je .rebboot
    int 0x10
    jmp .repboot_fortr

.rebboot
    ret

times (510 - ($ - $$)) db 0x00
DW 0xAA55

And here's the second: (fortr_kernel.asm)

[ bits 16 ]

fortrk_start:
    xor ax,ax
    mov bx,ax
    mov cx,ax
    mov dx,ax
    mov bx,0x7000

    mov si,fortr_outp
    call fortr_printf

    fortr_outp db 'Stage 2... Done!'

fortr_printf:
    mov ah,0x0E

But, if I compile it using this code:

nasm -f bin -o "fortr_foload.asm" "fortrSt.iso"

And play it in QEMU it does not boot it'll just output a white cursor and well, nothing.

But if I remove the lines:

%include "fortr_kernel"
call fortrk_start

And I even tried to rearrange the lines but sadly, it won't even work :( It will boot successfully! How can I fix this? TYSM in advance! :D Oh! And by the way, I'm really REALLY NEW to assembly so please help me out :D!

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • You transferred the NASM command line wrongly, the way you're showing it here it would delete your source. In both places where you have strings you're placing function calls directly in front of the strings. Assuming the call works, it will return to where the string is stored and try to execute the string as machine code, which most likely crashes or hangs. You seem to be confused as to where to put your `%include` directive. The way it is you will fall through to `start`, call `printf`, fall through past the end of the include file, then call `start` again. That is, an infinite loop. – ecm Sep 02 '20 at 12:58
  • Oh and you need to add `, 0` at the end of your strings for the intended working of your functions. Your logic expects a byte with the value zero to terminate the string to display. – ecm Sep 02 '20 at 13:03
  • Ok! i'll do it! :DDD! –  Sep 02 '20 at 13:07
  • Another duplicate: [Assembly with %include at the top - Printing Outputs Unexpected Result: just an " S"](https://stackoverflow.com/q/61072003) – Peter Cordes Jun 19 '21 at 12:17

1 Answers1

4

When you %include a file, it's placed exactly where you include it.

So,

[...]
fortr_outpf:
    mov ah,0x0E
    %include "fortr_kernel.asm"
    call fortrk_start
.repboot_fortr:
[...]

becomes

[...]
fortr_outpf:
    mov ah,0x0E
[ bits 16 ]

fortrk_start:
    xor ax,ax
[...]
    call fortr_printf

    fortr_outp db 'Stage 2... Done!'

fortr_printf:
    mov ah,0x0E
    call fortrk_start
.repboot_fortr:
[...]

You're directly injecting the included file in the middle of your codepath. If you want to do things this way (which you may want to reconsider, assembling and linking separate source files), %include it somewhere out of the way of the instructions the processor will execute.

Thomas Jager
  • 4,836
  • 2
  • 16
  • 30
  • Yes but, don't you think it'll make the file bigger than the assigned number of sectors for the MBR? –  Sep 02 '20 at 13:13
  • 1
    @user - Code you %include will take the same space no matter where you %include it. You can get a lot done in 512 bytes (the 1 sector that an MBR takes), e.g. switch to protected mode and set up an IDT and TSS, and page tables: [Is the address checked by the memory alignment check mechanism a effective address, a linear address or a physical address?](https://stackoverflow.com/a/68022489). x86 machine code is quite compact, especially 16-bit code where addresses are only 2 bytes. – Peter Cordes Jun 19 '21 at 12:20