I saw the following question on a test paper,
VarM DWORD ABBF01598h
Give the contents of registers al
, bx
, and dl
after the execution of
mov al, byte ptr VarM + 1
mov bx, word ptr VarM + 2
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.
al = b
bx = 0
dl = F
Please help me out in understanding these. Thanks in advance.
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.