### Author Topic: DW and DB difference  (Read 11543 times)

#### Sana Ullah

• Jr. Member
• Posts: 2
##### DW and DB difference
« on: March 18, 2015, 04:40:21 PM »
What is the main difference in these two examples i m new to ASM

Code: [Select]
[org 0x300]
mov ax,[num1]
mov [num1+3],ax
mov ax,[num1+1]
mov ax,[num1+2]

mov ax,0x4c00
int 0x21

num1: db 5, 10, 15, 0

Code: [Select]
[org 0x300]
mov ax,[num1]
mov [num1+6],ax
mov ax,[num1+2]
mov ax,[num1+4]

mov ax,0x4c00
int 0x21

num1: dw 5, 10, 15, 0

#### encryptor256

• Full Member
• Posts: 250
• Country:
• Win64 .
##### Re: DW and DB difference
« Reply #1 on: March 18, 2015, 05:44:08 PM »
DW - Define word
DB - Define byte

DB -----------------------
num: db 5
Define 5 which is 8 bit number (in 8 bit range).
OR
Define 8 bit number with initial value 5.

DW -----------------------
num: dw 5
Define 5 which is 16 bit number (in 16 bit range).
OR
Define 16 bit number with initial value 5.

Encryptor256's Investigation \ Research Department.

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2667
• Country:
##### Re: DW and DB difference
« Reply #2 on: March 18, 2015, 09:57:55 PM »
Hi Sana,

Thanks for joining us!

Can I say "charlie foxtrot" on the forum? I'd better not. I didn't say that.
Quote
What is the main difference in these two examples
The first one is even more massively wrong than the second one! Neither is likely to do anything useful.

We better start at the beginning. Encryptor256 has explained the difference between "db" and "dw". Did you understand it? We'll get back to that. But first...
Code: [Select]
[org 0x300]
We usually ask you, right off, "What OS?" Since you use "int 0x21", with a subfunction number in ah which would "return to DOS", I'm going to ASSume DOS.

ASSuming we've got that fixed, one way or the other, we can get back to the difference between "db" and "dw"...
Code: [Select]
mov ax,[num1]
Some assemblers "remember" that you said "num1" was "db" (bytes) and would barf up an error messages for this. Nasm has amnesia, and does not "remember" that "num1" is supposed to be bytes, and will obediantly do what you told it to do - which is to load both [num1] and [num1 + 1] into ax - a "word (16 bits) register. So ax will be 0x0a05 or 2565 decimal - probably not what you intend (although perfectly "legal"). You probably want to do:
Code: [Select]
mov al, [num1]
so that the size of the register (8 bits = 1 byte) matches the size of the number you defined with "db". Then al would be 5, as you probably intend.

Then it gets worse...
Code: [Select]
mov [num1+3],ax
Since you used a 16-bit (two byte) register, this will put the first byte (the 5) into [num1 +3] (overwriting the 0), and the second byte (the 0xA or 10 decimal) into [num1 + 4]. [num1 + 4] is beyond the end of your variable! Since there's nothing after it, this won't do any actual harm, but it definitely isn't "right"! If there had been another variable after "num1", you would have just scribbled on top of it.
Code: [Select]
mov ax,[num1+1]
Now we move another two bytes - at [num1 + 1] and [num1 + 2] - into ax. So ax is 0x0F0A (3850 decimal).
Code: [Select]
We add this value to [num1 + 3] and [num1 + 4] (the "illegal" byte that's past the end of our array). So memory looks like 5 0xA 0xF 0xF 0x19 (with the last byte outside of our array).
Code: [Select]
mov ax,[num1+2]
We load another two bytes into ax - the 0xF (15) that was in [num1 + 2], and 0xF (15) in [num1 + 3] - we overwrote the 0 that was there with the first store and the first add. So ax is 0xF0F.
Code: [Select]
We add that to [num1 + 3] and [num1 + 4] (which is "some other variable"... but nobody else was using it). So memory looks like 5 0xA 0xF 0x1E 0x28.

If you'd used al instead of ax up to here - matching the one byte you defined the numbers, it would probably do more like what you'd expect. Then, back to DOS.
Code: [Select]
mov ax,0x4c00
int 0x21

num1: db 5, 10, 15, 0

The second example is more nearly correct - outside of the "org" being "wrong"... or "strange" at least. You've defined your numbers as "dw" (two bytes, 16 bits) and you're using a word (16 bits) register to access them. The actual bytes in memory originally look like: 5 0 0xA 0 0xF 0 0 0 - so grabbing two bytes into ax is what you want. Note that we're on a "little endian" machine - in a multi-byte number, the least significant byte is stored first in memory, more significant bytes come later. This applies only to multi-byte numbers - it does not mean that "hello world" gets stored backwards!

... and that's the practical difference between "db" and "dw"...

Best,
Frank

#### Sana Ullah

• Jr. Member
• Posts: 2
##### Re: DW and DB difference
« Reply #3 on: March 24, 2015, 08:40:15 AM »
Frank Kotler - it was very helpful i got the idea