I am reading this wonderful skript on operating system programming
http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf
On Page 12 there is a simple bootloader.
If I understand correclty, the code shown is what you must write in NASM to get BIOS to print out characters.
What I dont get is this:
It says that
we need interrupt 0x10 and to set ah to 0x0e (to indicate tele-type mode)
and al to the ASCII code of the character we wish to print.
But the first instruction is:
mov ah , 0x0e ;int 10/ ah = 0eh -> scrolling teletype BIOS routine
I don't understand the comment on that line. Why doesn't the first line of code say:
mov ah, 0xeh
int 0x10
if thats what you need to do?
Thanks for help!
Although Chrono gave you an answer I'm not quite sure it answers your question. You seem to be asking why the comment says one thing and the code seemingly does another.
Decades ago a lot of reference material and some disassemblers used a slightly different default notation to represent decimal, hexadecimal, octal, and binary bases than you might see today. They specified the base as the last character(suffix) of the value. Common suffixes are:
b = binary 10101010b (decimal 170) base 2
d = decimal 170d (decimal 170) \ both d and t mean base 10
t = decimal 170t (decimal 170) /
h = hex 0AAh (decimal 170) base 16
o = octal 252o (decimal 170) base 8
If a number contains no alphabetic characters then it is assumed to be base 10 decimal. So this also applies:
no alphabetic character 170 decimal 170
Most assemblers will accept most of these suffixes, but they also will support the base being defined as a prefix. If a value doesn't end with an alphabetic character but starts with a 0 followed by a letter then the letter denotes the base. Common prefix bases are:
b = binary 0b10101010 (decimal 170) base 2
d = decimal 0d170 (decimal 170) \ both d and t mean base 10
t = decimal 0t170 (decimal 170) /
h = hex 0xAA (decimal 170) base 16
o = octal 0o252 (decimal 170) base 8
Most modern assemblers will support the forms specified as a prefix or suffix. Some assemblers may not support some of the prefixes and suffixes like t
.
If you specify numbers with a prefix base then stick with prefixes throughout the whole file. If you specify numbers with a suffix base then stick with suffixes throughout the whole file. You can mix them up, but it is best to be consistent in a file.
What does this mean:
int 10/ ah = 0eh -> scrolling teletype BIOS routine
int 10
contains no letters so it is decimal 10
(or hexadecimal a
). 0eh
ends with a letter and doesn't start with 0 and a letter so h is the suffix. h
means hexadecimal. So 0eh
is hexadecimal 0e
(or decimal 14
).If you were to put that into assembler code for the BIOS it would look like (using hexadecimal suffix):
mov ah, 0eh ; Decimal 14
int 0ah ; Decimal 10. The 0 in front makes sure the assembler knows we don't mean register ah!
Using prefixes (hexadecimal in this example):
mov ah, 0xe ; Decimal 14
int 0xa ; Decimal 10
Or if you want to use decimal (no prefix or suffix):
mov ah, 14 ; Decimal 14
int 10 ; Decimal 10
But you may now be saying Hey Wait! that is wrong because the BIOS video interrupt is 0x10
(or 16
decimal) you are correct! We have just learned that the comment is wrong or at best VERY ambiguous. The comment should have said:
int 10h / ah = 0eh -> scrolling teletype BIOS routine
You may wish to contact the author of the comment / code and let them know that their comment is inaccurate. The code they wrote is correct.
If the assembler supports them I prefer prefixes like 0x
, 0b
, 0o
instead of the suffixes h
, b
, o
because it is possible for some suffixes to form register names, or other identifiers and symbols. When using suffixes, if you have a value that must start with a letter (ie: A to F in hexadecimal) add a 0 to the beginning to let the assembler know you are representing a value. As an example AAh
would have to be written as 0AAh
, and Bh
would have to be written as 0Bh
.