;The key to this lesson is experimentation. Mess with things to find out what happens. This lesson will be a difficult lesson, but the next lesson and future lessons are alot easier.

;This lesson will be more on some "pre-processor" stuff, that is, no new instructions in this lesson. Instead, we're going to talk about stuff necessary for continuing the right way. We need to talk about data directives. What if we didn't want to rely on the stack to save our data? The syntax is "name size value." "name" is a label to represent the data, and it basically holds the value that represents the location of the first byte (we call these values "pointers," by the way). You will want to put these after the "terminate," because if you put them before begin, it will mess up the header and the program will not run. If you put them before terminate but after begin, data will be executed as if they were instructions and the program will crash. If you put data after "end" it will not be automatically loaded. So, until later, we have to keep these things to between "end" and "terminate".

;The size option can be one of many types. The first type groups is the
;"define data" group, which begins with a "d" and the second letter is
;a letter that represents the actual size.
;db = define 1 byte with value at the location
;dw = define 2 bytes (1 word) with the value at the location
;du = alias for dw (u is for 2 byte unicode)
;dd = define 4 bytes (1 dword [double word]) with the value at the location
;dp = define 6 bytes (pword) with the value at the location
;df = alias for dp
;dq = define 8 bytes (qword [quad word]) with the value at the location
;dt = defined 10 bytes with value at the location

;Now if you try to, say, move a db into the 4 byte eax register, it will throw a fit and complain that the "oprand sizes do not match." This is because they have to match. There is a way around this problem (next lesson), but for right now you have to learn how to override the sizes. If you make "meow db 0," you can move 4 bytes into the eax register by saying "mov eax, dword [meow]." To move 1 byte into that 4 byte register, you can either write "mov al, [meow]" and deal with the fact the rest of the register isn't filled with 0s (you could "mov eax, 0" first) or you will have to wait until the next lesson to figure out how to do this.

;Size modifiers:
;byte        = 1 byte
;word        = 2 bytes
;dword        = 4 bytes
;fword        = 6 bytes
;pword        = 6 bytes
;qword        = 8 bytes
;tbyte        = 10 bytes
;tword        = 10 bytes
;dqword        = 16 bytes
;xword        = 16 bytes
;qqword        = 32 bytes
;yword        = 32 bytes

;Now with define data, you can specify of the same size without using a separate line by separating the values with commas ("meow db 1, 2"). You can also represent letters by using either single quotes or double quotes, and it will replace each letter with it's numerical value (based on ascii charts [see google]). Now, to make matters interesting, it doesn't simply place these as bytes, unless you're using db. If you're using dw or du, for example, it will write each letter's value as a separate 2 byte section. so "dw 'ab'" comes to 4 bytes, not 2. Oh, and before I forget, the label is optional, here.

;Now comes the part that's hard to swallow. In x86, things are "little endian." This is usually not a big problem, but it is confusing and can result in confusing bugs. The bytes are all reversed. This means that "dd 0x12345678" is the same as "db 78, 56, 34, 12." As long as your data directives match, this will not appear very often. However, if they do not, this will become an issue for you. So remember that bytes are written backwards on x86 machines and you will be ready for when you do have to face the issue.

;Now that that headache is out o the way, we also have "reserve data." They correspond to their "define data" counterparts, but they are very different in use. The value represents the AMOUNT of data, not the actual data itself. If the assembler can avoid writing data reserve data into the binary, it will. The trick is, if there is no defined data or instructions after the reserve data, it will not actually be in the binary, but rather the labels will still correspond to the proper locations in RAM. As such, when it does put it into the binary, it has the value of 0, however you cannot simply assume that it will be 0 when you go to use it, because if the assembler found a way of getting out of putting it in the binary, it could be *ANYTHING*, so always initialize your data (give your data some initial values via mov instructions or simialr) before you use it.

;The value "?" can be written for a single "define data" in which case it then acts as "rX 1" where X represents the size.

;Lastly, there is a "file" size. It basically includes a file into the binary "as is" without trying to interpret it. The label will point to the first byte of this file. You can also specify a starting location using :, then a number of bytes to load after a comma. Ex:
;label file "filename":10,3 ;Load bytes 10, 11, and 12 from a file

include "macros.inc"
begin
        mov eax, [meow]
        mov ebx, [meow+4]
        mov ecx, [meow+8]
        mov edx, [meow+12]
        mov esi, dword [kitty] ;This ends up being the first 4 bytes of LearnerKernel.
        int3
terminate
meow dd 0xdeaddead, 0x12345678
db "abcd", 1, 2, 3, 4
kitty file "kernel.bin" ;The first lesson must be compiled for this to work
end

;Do not fret, as from here on out, most of the lessons are alot easier. However, this is only true if you completely understand this lesson and the previous lessons. If you do not, please go back and experiment and brush up on everything.

;Oh, and if you're really bored, make a new file with the follow contents.:
;format binary as "txt"
;db "Hello, i'm a data directive!"

;Then assemble that and look at the resulting "program." Experimenting with that should help with your undersanding. It's also useful to use fasm to make files in a special format that you make. The "format" line basically tells fasm to make the file name end with ".txt" which makes windows treat the file as a text file and open it with notepad. Those of you on linux do not need that line. The "binary" means you don't want to add any special pre-made headers to the resulting file.


Get your own web kitty here!
┬ęCopyright 2010, 2011, 2012, 2013, 2014, 2017. All rights reserved.