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.