I am making a program in x86_64 assembly language and it requires me to offset a memory address by a variable. I am trying to use the *
to multiply the address by edx
however, I get the following error:
kernel.asm:23: error: invalid operand type
Why is this happening and how do I fix my problem? Here is my code:
mov edx, 1
mov ebx, 0xb8000+160*edx
inc edx
Thing is that your instruction is invalid, because memory operands are required to be in wrapped in square brackets. Applying this change you would have mov ebx, [0xb8000+160*edx]
. Using the Intel/MASM/DOS notation for hexadecimal numbers as NASM also allows, you'd get mov ebx, [0b8000h+160*edx]
. This instruction would still be wrong, because the SIB byte of the instruction encoding on x86 ISA only allows scale factors of 2
,4
and 8
as described in Table 2-3 of the Intel Manual. 160 is not a valid scale factor. Finally, you want to calculate the address, so better use LEA
and not mov: lea ebx, [0b8000h+2/4/8*edx]
.
You have to calculate the value with other instructions like MUL
, IMUL
, SHL
or INC
to get the resulting value you want.
For example, you can do the following calculation to position your cursor (with ECX=X and EDX=Y) assuming an 80x25 text mode (using IMUL
instead of MUL
as suggested in the comments):
mov ecx, X ; where X might be [esp+8] or [xpos] or whatever
mov edx, Y ; you may not need a register, imul-immediate can load
; with inputs in registers
imul ebx, edx, 160 ; calculate line offset
lea ebx, [0B8000h + ebx+ecx*2] ; add column offset and base address
; Now EBX is Y*160+X*2