Average of marks with bytes

后端 未结 1 1183
野趣味
野趣味 2021-01-21 18:15

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 rc         


        
相关标签:
1条回答
  • 2021-01-21 18:35

    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.

    0 讨论(0)
提交回复
热议问题