平均字节数 [英] Average of marks with bytes

查看:30
本文介绍了平均字节数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在计算 3 分的平均值:

I'm computing the average of 3 marks:

g0  dw  70
g1  dw  100
g2  dw  65  

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).

如何将成绩转换为字节?使用 db 是不够的,因为那样我必须将 ax 更改为 al,但它最终会导致溢出.我不能指示 mov/add 只从 [g*] 获取一个字节,因为这会导致操作数大小不匹配.

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.

我正在使用 yasm.

I'm using yasm.

推荐答案

如果您使用另一个寄存器进行添加,您可以将变量更改为字节.所以以下是可能的:

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  

使用MOVZX 指令并指明内存参考大小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.

也不需要使用 64 位操作数大小.32 位是标准"对于大多数指令,x86-64 的操作数大小.

There's also no need to use 64-bit operand size. 32-bit is the "standard" operand-size for x86-64 for most instructions.

当然,您可以将 eaxedx 寄存器引用分别更改为 raxrdx,因为这些值已经零扩展到整个寄存器宽度.如果您要添加超过 2^32/100 个成绩,您可以使用它来避免溢出.

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.

如果你重复这个固定次数,mov ecx, count 而不是使用那么多的 inc 指令.inc 如果这是在一个循环体中并且你增加了一个指向成绩数组的指针,那么 inc 会有意义,但是完全展开的部分好处是不必 inc任何东西都可以算作互动.

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.

这篇关于平均字节数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆