Print a number in NASM - building an x86 Bootsector

2.5k views Asked by At

I just started messing around with assembly language and I tried to print the number 9 on console. Here is what I wrote:

global _main

section .data

    digit equ 9

section .bss

section .text

    _main:

        mov edx, 1  
        mov ecx, digit
        add ecx, 48
        mov ebx, 1
        mov eax, 4  
        int 21h     

    ret

I know I can do it using extern _printf but I want try it with interrupts. I thought 21h is a windows interrupt. So, what interrupt code should I use?

1

There are 1 answers

17
David Hoelzer On BEST ANSWER

Here's an example from a course that I teach. This is a raw bootsector that you can compile directly as an object file and use as a bootable floppy or USB image in something like Qemu, VirtualBox, VMWare, Bochs or a real machine.

This makes use of the real mode BIOS interrupt 16 (0x10) for character output. I think this is what you're trying to get at with your question. :)

;
;   x86 real mode boot sector template
;   David Hoelzer, 2011 - Assembly Bootcamp
;
;   x86 architecture systems all support MBR style boot sectors.  An
;   MBR boot sector must be 512 bytes in length and have machine
;   language code originating at 0000:7c00.  Additionally, it must
;   have the signature "0x55aa" as the final word in the sector or it
;   is not a valid boot sector.


; This is a basic Hello World example.  Here we will uses BIOS interrupt
; 0x10 which can be used for all manner of screen output.  This version uses
; the write-string function, which is int 0x10, ah = 13h:
;
;   BIOS Write String: INT 10h
;       AH = 13h    Function number
;       AL -        Bit 0 - Update cursor position after writing?
;                   Bit 1 - String contains attributes?
;       BH          Video page number       
;       BL          Attributes to apply to string for text only strings
;       CX          Number of characters to print
;       DH          Row to start printing at (0,0 is top left corner)
;       DL          Column to start printing at
;       [ES:BP]     Far pointer to string to print

org 0x7c00      ; BIOS will load the MBR to this location 
                ; and then jump here to continue execution


                mov ax, cs          ; Where are we now?  
                                    ; Could be 0000:7c00 or
                                    ; 07c0:0000 or some other
                                    ; combo.
                mov ds, ax          ; Our data is here too.
                mov es, ax          ; ES:BP is the pointer
                                    ; to the string.  ES should
                                    ; match DS and CS.
                mov bp, message     ; Offset of our message
                mov bh, 0           ; Video page 0
                mov bl, 00001111b   ; Attributes:  Bright white foreground
                                    ; on a black background, no flashing
                mov cx, [length]    ; String length
                mov al, 1           ; Bit zero is on: Update position
                                    ; Bit one is off: No attributes in string
                mov ah, 0x13        ; Function number
                mov dx, 0           ; Row,Column = 0,0
                int 0x10            ; Call the function

                jmp $

message     db      "Hello, World!"
length      db      (length - message)
                            ; As stated above, the boot sector must 
times   510-($-$$) db 0     ; Create padding to fill out to 510 bytes
dw      0xaa55              ; Magic number in the trailer of a boot sector
                            ; We write it as 0xaa55 because we're little
                            ; endian and it will be reversed to the required
                            ; 0x55 0xaa