There's a lot of new stuff in this program! I'll start explaining...BTW, I only explain the new things.
.stack 10 : Is like .stack only now the stack will be 10 instead of 1024 bytes long.
dw 0 : Define Word (like db, only a word this time)
dd : Define Double word (like dw, only 2 words this time)
db 3 dup ("!") : Defines 3 bytes with the value "!".
Same as: db "!!!"
mov es,[video_segment] : Important one. If you type something
between square brackets [] in assembly, it means you don't want the location
of the identifier but the contents. So ES will be loaded with the value
0B800h (note the zero before the B, if you don't do this, the assembler
thinks it's an identifier)
mov [value_one],"H" : About the same as above. The byte
value_one will be loaded with the value "H" (note, if you type ASCII between
"" the assembler will generate the ASCII number. Eg. space bar is 20h,
so " "=20h)
mov byte ptr [value_two],"e" : "Byte ptr" lets the assembler
know you want to store a byte. This must be done, because value_two was
declared as a word. (DW) If we would have declared it a byte (DB), like
value_one, you could have ommited the "byte ptr".
mov byte ptr [value_two + 1],"l" : Same as above, except
for the +1. The +1 means the assembler has to add one to the address of
value_two. This way, an "l" is stored in the second byte of the word value_two
(still get it?)
mov word ptr [value_three + 2],2020h : Word ptr means
that we want to store a word. (this way the bytes will be stored in reverse
order, see part 1) The +2 indicates that we want to store the value in
the second word of the dword value_three.
inc byte ptr [di] : First we loaded the address of value_four
into DI. INC adds one to a value. But, not DI is increased. Since DI is
in brackets [DI] the contents of the memory location DI points to (value_four)
will be increased. Byte ptr again indicates that the value is a byte.
If you don't add a "ptr" where one IS needed, the assembler (TASM) wil
give an "argument needs type override" error. You don't need a "ptr" everywhere,
if the assembler can know what type you want to store, you don't need a
"type override". For example "mov es,[video_segment]". Since ES is a word
and video_segment was declared as a word also, you don't need a type override.
Just see for yourself, you can just leave them everywhere, and see at wich
lines the assembler gives an error. In the memory from value_one to value_five
now stands: Hello everybody!!!
It will only look like this, when the first line on the screen is blank. The first byte (B800:0000) is the first character on the screen. The second byte is the atribute of the character. An atribute is a value that indicates how the character looks, eg. what colour. Below is a list of all possible atributes and their means.
0 = Black
1 = Blue
2 = Green
3 = Cyaan
4 = Red
5 = Magenta
6 = Brown
7 = White
So 07h means: white text on a black background. Now suppose we want
blinking, bright red text on a blue background.
Red=4 Bright red=4+8=12=0Ch. Blue=1*16=16+8=24=18h ==> 18h + 0Ch =
24h
xor di,di : eXclusive OR, a logical instruction. It works
this way:
| XOR | 0 | 1 |
| 0 | 0 | 1 |
| 1 | 1 | 0 |
Now, try to figure out what this little part of the code does yourself. I'll explain it below, but please, try it yourself first. You'll learn from that. With programming you always have to try and figure out things. Also, don't be afraid to change the code, just do crazy stuff and try! So what if the system crashes!
Fist we load DI with 0, we do this because we want stosw to store the data at an offset zero. Then we load SI with the offset of the message we want to display. After that we load CX with 19, because the message has a length of 19 bytes and so we have to loop 19 times. We load AH with 07, this is the attribute of the characters we want to display. (07=white on black) Now we clear the direction flag, so that SI and DI are increased and not decreased. After all this initialization the actual loop starts here. First it loads AL with the value on DS:SI. AH was 07, so AX will be 07xxh. Now we store AX at ES:DI (the video memory) Because we store a word, it is stored in reverse order (see part 1) So the the first two bytes of the video memory look like this: xx 07. DI and SI were increased, so we just loop 19 times to store all characters this way. Simple huh?
Okay, that's how the program works. I hope you learned something... Writing this message to the screen can, of course, be done a lot easier. The first part of the code was just to show you how addressing memory works. Also, with this little text, you better use INT 21h Function 09. But if you want to clear the screen (writing 2000 spaces), you better do it this way.