0

Implementing global and extern instructions in assembly seem not to work

I'm currently creating a bootloader in assembly, but calling or jumping into a label from another file brought no errors, but having wrong output

Making use of %include <path/to/directory> works fine, but I also need to make use of the call instruction too

Here's what I tried:

I had to reduce the code to minimal

#start.asm

[bits 16]
global _start
extern printc

_start:
    mov ah, 0x0e
    mov al, "H"
    call printc

    jmp $

times 510 - ($-$$) db 0

dw 0xaa55

#print.asm:

[bits 16]

global printc

printc:
    int 0x10
    ret

I compile it using:

nasm -f elf64 start.asm -o start.o nasm -f elf64 print.asm -o print.o

ld -s -Ttext=0x7c00 start.o print.o -o printer.elf

objcopy -O binary printer.elf printer.bin

and I used the qemu emulator qemu-system-x86_64 -drive format=raw,file=printer.bin

And the output is:

Booting from Hard Disk...
_

what am I not getting right?

  • That's too minimal, you didn't show any build commands for how you were trying to assemble and link this. Also, use `code blocks` (triple backticks), and don't double-space your code. A separate code block for each file is good. – Peter Cordes Jun 04 '23 at 16:04
  • `times 510 - ($-$$) db 0` / `dw 0xaa55` is handled at assemble-time for that one file. Linking it with something else will put the .text section of from the other `.asm` after the 512 bytes from the first file, where it won't get loaded by the BIOS. Look at the size of your `.bin` file, and check a hexdump or use `ndisasm -b16` to see where your code is. If you want to use the linker this way, you need a linker script to generate the `0xaa55` signature at the end, as in [What exactly does ". = 0x7c00" in a linker script do?](https://stackoverflow.com/q/43348913) – Peter Cordes Jun 04 '23 at 16:38
  • [Role of linker scripts when writing x86 assembly](https://stackoverflow.com/q/59700854) has another detailed example. – Peter Cordes Jun 04 '23 at 16:44
  • 1
    Yeah, I noticed that the codes from the second file is placed after the magic number (0xaa55) after using hd and xxd, but I couldn't understand how to make it right. Now I know where to look, rather than thinking about something else that isn't the problem. I'll check the links you provided. Thanks @PeterCordes – Junior Ohanyere Jun 04 '23 at 17:29
  • [Calculating padding length with GAS AT&T directives for a boot sector?](https://stackoverflow.com/q/47859273) mentions the case of multiple `.o` files, and shows a usable linker script for linking them, and having the linker add the signature. Not a duplicate, though, since it's primarily about using GAS instead of NASM. The fact that no assembler directive can work when you're linking multiple object files (instead of using `%include` of source files) is kind of a bonus part of Michael Petch's excellent answer. (Definitely check out his other answers, like his general bootloader tips) – Peter Cordes Jun 04 '23 at 18:19
  • For a bootloader you should ask NASM to use the BIN format. Instead of `nasm -f elf64 start.asm` write `nasm -f bin start.asm`. – Sep Roland Jun 04 '23 at 19:12
  • using the `nasm -f bin ` format is not possible with `extern` instruction – Junior Ohanyere Jun 05 '23 at 04:23
  • I've tried a hell of things and could not still resolve it Here's my current progress for the start.asm file ```assembly [bits 16] global _start extern print _start: xor ax,ax mov ds,ax mov es,ax mov bx,0x8000 cli mov ss,bx mov sp,ax sti cld mov ah, 0x0e mov al, "H" call print jmp $ times 510 - ($-$$) db 0 dw 0xaa55 – Junior Ohanyere Jun 05 '23 at 06:06
  • I guess I'll have to stick with the %include directive, but please I hope it won't affect later, especially in the case of loading the kernel – Junior Ohanyere Jun 05 '23 at 06:25

0 Answers0