You can change the variables to bytes if you use another register for the adding. So the following is possible:
g0  db  70
g1  db  100
g2  db  65  
Use the MOVZX instruction and indicate the memory reference size BYTE:
xor ecx, ecx              ; clear counter register and break dependencies
movzx eax, BYTE [g0]      ; movzx loads g0 and fills the upper bytes with zeroes
inc ecx
movzx edx, BYTE [g1]      ; move byte from g1 to dl and zero-extend
add eax, edx              ; add the widened integers
inc ecx 
movzx edx, BYTE [g2]      ; the upper half of RDX is zeroed automatically by this instruction, but 32-bit is fine.
add eax, edx
inc ecx
xor edx, edx
div ecx                   ; unsigned division of EAX / 3
                          ; quotient in EAX, remainder in EDX
;mov [average], al        ; or do whatever you want with it.
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 and edx register references to rax and rdx, respectively, because the values have been zero-extended to the full register width.  If you had more than 2^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 many inc 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 to inc anything to count interations.