PSS - Pragmatic problem solver
BITS 16 mov ax, 'A' add ax, '0' mov dx, 0x3f8 out dx, al mov eax, 0xc000 jmp eax
directive. This tells compiler that we are want to produce a 16 bit binary.
nasm -o a16.bin a16.asm
) is represented using 3 bytes. b8 is the opcode for mov instruction while the following two bytes is number 0x41 written using two bytes in little endian format.
mov ax, 0x41
) encodes instruction to add
to whatever value is in
register and store it back into
. Notice how ax is 16 bit register and the immediate operand (0x30) is 8 bits in size. ADD instruction (
) has numerous options that customize its operation. In this case we use
to tell ADD op to use
register as source and destination.
. This instruction does similar thing to
in the first line. Notice how the second byte changed from
. This is because opcode of this instruction encodes which register is used. In this case this instruction tells CPU to use register
instruction is a simple one. It's a one byte instruction telling our CPU.
. We've seen
before. We also know that
is target of our jump instruction written in little endian format. Two questions that remain are: 1. What is that
in front of
? and what is that
at the end of the instruction?
is part of the instruction which tells CPU to use non-default instruction length. In our 16bit program default length for
instruction is 16 bits (e.g.
register). Here we are putting value
into 32bit register
. In our case
can be written as
. We just added a number of zeros to get a 32bit number. Now if we write
in little endian format we get
. This is exactly sequence of digits that we see following
is the last instruction in our program. 0x66 serves same purpose as in previous instruction - it tells CPU to "switch to" using 32 bit operands.
is opcode for
BITS 32 mov eax, 'A' add eax, '0' mov edx, 0x3f8 out dx, al mov eax, 0xc000 jmp eax
compiler that we want to output 32 bit binary. Also notice that instead of using
as operand we use
is name of 32 bit register while
is used to name 16 bit register. As a matter of fact
represents lower 16 bits of
prefix in front of second last instruction is not there any more. In 32bit mode default operand size is 32 bits so there's no need for prefix in this case.
BITS 64 mov rax, QWORD 'A' add rax, QWORD '0' mov rdx, QWORD 0x3f8 out dx, al mov rax, QWORD 0xc000 jmp rax
directive telling compiler that it should output 64 bit program we use
to explicitly specify that immediate operands should be 8 bytes in size.
prefix. This is so called REX prefix. It's available in 64 bit mode only and in this case tell CPU that the instruction should use 64 bit operand size. Keep in mind that some instructions, in 64 bit mode, do not use 64 bit operand by default but instead use 32 bit ones. MOV is an example of such an instruction.