Difference between byte ptr and word ptr

user379888 picture user379888 · May 2, 2012 · Viewed 29.8k times · Source

I saw the following question on a test paper,

Question

VarM DWORD ABBF01598h

Give the contents of registers al, bx, and dl after the execution of

  1. mov al, byte ptr VarM + 1
  2. mov bx, word ptr VarM + 2
  3. mov dl, byte ptr VarM + 3

Now I know word ptr and byte ptr by definitions but I am unable to pickup the concept of them.

According to me

  1. al = b
  2. bx = 0
  3. dl = F

Please help me out in understanding these. Thanks in advance.

Answer

Jerry Coffin picture Jerry Coffin · May 2, 2012

In the cases you're looking at, the byte ptr and word ptr don't accomplish much. While harmless, the assembler already "knows" that al and dl are byte-sized, and that bx is word-sized.

You need something like byte ptr when (for example) you move an immediate value to an indirect address:

mov bx, some offset
mov [bx], 1

This won't normally be allowed -- the assembler has no way to know whether you want the 1 written into a byte, a word, a double-word, possibly a quad-word, or what. You fix it by using a size specification:

mov byte ptr [bx], 1  ; write 1 into a byte
mov word ptr [bx], 1  ; write 1 into a word
mov dword ptr [bx], 1 ; write 1 into a dword

You can get the assembler to accept the version without a (direct) size specification:

mov bx, some_offset
assume bx: ptr byte

mov [bx], 1   ; Thanks to the `assume`, this means `byte ptr [bx]`

Edit: (mostly to reply to @NikolaiNFettisov). Try this quick test:

#include <iostream>

int test() { 
    char bytes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    _asm mov eax, dword ptr bytes + 1
}

int main() {
    std::cout << std::hex << test();
    return 0;
}

The result I get is:

5040302

Indicating that even though I've told it dword ptr, it's adding only 1 to the address, not 4. Of course, somebody writing a different assembler could do it differently, if they chose.