在字节,单词和双字之间转换

时间:2013-09-18 01:17:13

标签: assembly x86

所以我正在为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上,所以很抱歉)。

3 个答案:

答案 0 :(得分:2)

您可以使用MOVZXMOVSX指令将字符/字符号扩展(无符号)和符号扩展(已签名)字节/字转换为字/ 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]