I'm computing the average of 3 marks:
g0 dw 70
g1 dw 100
g2 dw 65
with
xor rax, rax
xor rcx, rcx
mov ax, [g0]
inc rcx
add ax, [g1]
inc rcx
add ax, [g2]
inc rcx
xor rdx, rdx
idiv rcx
The grades don't need to be words, because bytes would be enough as for the average, but the sum must be a word to avoid overflow (with this algorithm, that is).
How can I convert the grades to bytes? Using db
isn't enough, because then I would have to change ax
to al
, but it would cause an overflow at the end.
I cannot instruct the mov/add
to only take a byte from [g*]
, as it would cause a mismatch in the operand sizes.
I'm using yasm.
You can change the variables to bytes if you use another register for the adding. So the following is possible:
Use the
MOVZX
instruction and indicate the memory reference size BYTE:There's also no need to use 64-bit operand size. 32-bit is the "standard" operand-size for x86-64 for most instructions.
Of course, you can change the
eax
andedx
register references torax
andrdx
, respectively, because the values have been zero-extended to the full register width. If you had more than2^32 / 100
grades to add, you could use that to avoid overflow.If you're repeating this a fixed number of times,
mov ecx, count
instead of using that manyinc
instructions.inc
would make sense if this was in a loop body and you were incrementing a pointer to an array of grades, but part of the benefit of fully unrolling is not having toinc
anything to count interations.