所以我正在为x86汇编类做第一次任务,而且我已经迷失了(很棒)。也许我读错了,但看起来我需要将一个字节转换为一个单词,我可以做到,一个单词的双字,我一点也不知道怎么做。考虑到我已经做了大量的调查,我猜我误解了我需要做的事情。这是提示:
假设.data段中的以下定义:
arrayB: db 170, 193, 57
arrayW: dw 0, 0, 0
arrayD: dd 517, 1045, 2000
编写一个与以下高级语言语句等效的汇编程序:
arrayW[0] = arrayB[0] + arrayD[0];
arrayW[1] = arrayB[1] + arrayD[1];
arrayW[2] = arrayB[2] + arrayD[2];
提前致谢;我不知道我在做什么(无论是在集会还是在SO上,所以很抱歉)。
答案 0 :(得分:2)
您可以使用MOVZX
和MOVSX
指令将字符/字符号扩展(无符号)和符号扩展(已签名)字节/字转换为字/ dwords。
例如:
movzx ax,byte [arrayB + 0] ; ax becomes 0x00AA (== 170)
movsx ebx,byte [arrayB + 0] ; ebx becomes 0xFFFFFFAA (== -86)
要将dword中的值缩小为单词,您只需抓住低位字即可。请记住,如果dword在其高位字中包含非零位,您将丢失该信息(这不是您在问题中发布的值的问题;它们都适合16位):
mov ax,word [arrayD + 4] ; put the lower word of the 2nd dword in ax
答案 1 :(得分:1)
我认为高级语言会对此抱怨不已。 (但谁关心HLL的作用?)对于将双字转换为单词而言,你是非常正确的。一般而言,在不丢失信息的情况下,您无法做到这一点。在这种情况下,我们可以通过检查看到双字数组中的所有三个数字都适合单词,所以你可以截断它们并称之为“转换”我猜。 (可怕的任务,恕我直言)
对于三种不同尺寸的阵列,可能会给您带来更多麻烦。索引0很容易。但是对于索引1,您需要从[arrayB + 1]
获取一个字节,将其添加到从[arrayD + 4]
截断为单词的双字,并将结果字存储在[arrayW + 2]
中。您可以找出索引2的样子。你说你知道怎么做字节到字部分,所以你知道如果你做'mov ax,[ArrayB]'它会得到170和193,对吗?
如果您的代码有问题,请试一试并回来。
答案 2 :(得分:0)
这是一项非常简单的任务,但有一些微小的时刻。首先,如果要将较大的数据类型转换为较小的数据类型,则应确保这些值足够小以适合较小的类型变量。在你的情况下,它是“单词”,所有数字都小到足以容纳两个字节。
第二个问题是数字的符号。他们是签名还是未签名?在示例中,只有正数,但您应该在常见情况下明确说明。
从较小的变量大小转换为较高的变量非常简单,您应该将movzx
用于无符号变量,或movsx
用于签名。
从较大的数据大小转换为较小的数据甚至更简单。您只需使用数字的下半部分并忽略较高的部分。
这是简单的实现(FASM语法):
movsx ax, [arrayB] ; it is arrayB[0]
add ax, word [arrayD] ; it is the lower word of arrayD[0]
mov [arrayW], ax ; it is arrayW[0]
movsx ax, [arrayB+1] ; arrayB[1]
add ax, word [arrayD+4] ; arrayD[1] - note the array element size is 4 bytes long.
mov [arrayW+2], ax ; arrayW[1] - array element size is 2 bytes.
movsx ax, [arrayB+2] ; arrayB[2]
add ax, word [arrayD+8] ; arrayD[2]
mov [arrayW+4], ax ; arrayW[2]