6

The following site "Writing Boot Sector Code" provides a sample of code that prints 'A' to the screen when the system boots. From what I have been reading don't you have to use INT opcode to get BIOS to do certain things? How does the code below, from the site referenced above work without using interrupts? What portion of code actually tells the hardware to print 'A' to the screen?

Code in question:

.code16
.section .text
.globl _start
_start:
  mov $0xb800, %ax
  mov %ax, %ds
  movb $'A', 0
  movb $0x1e, 1
idle:
  jmp idle 

APPENDING TO ORIGINAL QUESTION

If I use the following code does the BIOS call write to the text buffer for me? The buffer starting at address 0xb800?

   # Author: Matthew Hoggan
   # Date Created: Tuesday, Mar 6, 2012
   .code16                        # Tell assembler to work in 16 bit mode (directive)
   .section .text
   .globl _start                  # Help linker find start of program
   _start:
       movb $0x0e,     %ah        # Function to print a character to the screen                 
       movb $0x00,     %bh        # Indicate the page number
       movb $0x07,     %bl        # Text attribute
       mov  $'A',      %al        # Move data into low nibble                   
       int  $0x10                 # Video Service Request to Bios                             
   _hang:                         
       jmp  _hang                 
       .end   
Matthew Hoggan
  • 7,402
  • 16
  • 75
  • 140
  • 1
    It does. Though, the buffer location really depends on the graphics chip. On monochrome adapters you'd use segment 0xb000 instead of 0xb800. – Alexey Frunze Mar 12 '12 at 06:29

3 Answers3

9

Direct answer to your question: The line "movb $'A', 0" effectively completes the print to the screen (and the following line, "movb $0x1e, 1" specifies what color it should be).

Longer answer: The video hardware draws the screen based on the contents of memory. When in text mode, the video hardware starts drawing based on memory segment 0xB800. Whatever is at byte 0 defines the character to be drawn at the first text cell on the screen. The next byte defines the attributes (foreground color, background color, and blink status). This pattern repeats (char - attr - char - attr) throughout the entire screen.

So, technically, my direct answer wasn't true. The 2 'movb' statements simply stage the letter 'A' to be printed. 'A' is not printed until the next time hardware refreshes the display based on the memory.

Multimedia Mike
  • 12,660
  • 5
  • 46
  • 62
  • Two questions, the hardware will refresh at its own refresh rate? Is that based on CPU cycles? If I wanted to read more up on this do you have any good references? – Matthew Hoggan Mar 11 '12 at 07:40
  • Yeah, the hardware does its own thing. When I think of these text modes, I'm thinking of MS-DOS from 30 years ago. Monitors were running at 50 or 60 Hz then (PAL or NTSC, respectively). So that was 50 or 60 refreshes per second. Most video hardware allows software to poll a bit in order to learn if a vertical refresh is occurring. This is useful for preventing graphical flicker but it's not usually a huge concern for text mode. As for references, I guess the Wikipedia article for text mode would be a good start: http://en.wikipedia.org/wiki/Text_mode – Multimedia Mike Mar 11 '12 at 07:58
1

At boot, you're in a default screen mode - in this case a text screen mode. Your example program is writing directly into the character buffer that's displayed on the screen for that text screen mode. Setting the data segment register to 0xb800 is getting things set up to point at that buffer. Check out this tutorial for more information.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • In that link you sent me he is using INT. In the code above, mov 0xb800 to ax sets up a pointer to buffer? Why does he have two mov lines? Why not just mov $0xb800, %ds?. Another question is what does mov $'A', 0 accomplish? Does it move 'A' to a relative address '0'? Also movb $0x1e, 1 moves the attribute to relative adress 1? I am still a bit confused. – Matthew Hoggan Mar 11 '12 at 07:37
  • Sorry - I just meant the link to be an explanation of the data segment parts. You *can't* move a constant directly into `ds`, which is why it's a two-step process. Your example program sets the data segment to `0xb800`, then puts an ASCII `'A'` in `0xb800:0000` and a literal `0x1e` in `0xb800:0001`. @MultimediaMike's answer is a great explanation, I think. – Carl Norum Mar 11 '12 at 07:38
  • This a side project of mine, I hope you don't mind all the questions. Your help is greatly appreciated. Above I have appended on to my original question to get a better understanding of what is going on. Could you expound a little more on the subject? – Matthew Hoggan Mar 12 '12 at 05:29
  • I'm afraid I don't know enough about this DOS kind of stuff; you might want to check out the link I have in my answer. I think that guy is talking about the same kind of things. – Carl Norum Mar 12 '12 at 05:50
0

Basically when you call INT 10h, BIOS will execute a routine that does almost the same thing, by writing characters and their attributes to video memory. It is, however useful to know how to write and execute these routines yourself so if and when you decide to switch the CPU into 32-bit protected mode, you can still print characters to the screen because in that mode you will no longer be able to call BIOS interrupts.

  • Is the change after switching into 32-bit protected mode or after switching out of 16-bit real mode into 16-bit protected mode? – amyiris Nov 03 '21 at 22:04