4

所以我正在为一个 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 中,对此感到抱歉)。

4

3 回答 3

2

MOVZX您可以使用andMOVSX指令将字节/字零扩展(无符号)和符号扩展(有符号)到字/双字。

例如:

movzx ax,byte [arrayB + 0]  ; ax becomes 0x00AA (== 170)
movsx ebx,byte [arrayB + 0] ; ebx becomes 0xFFFFFFAA (== -86)

要将值从 dword 缩小到 word,您只需抓住较低的单词。请记住,如果 dword 在其高位字中包含非零位,您将丢失该信息(尽管您在问题中发布的值不是问题;它们都适合 16 位):

mov ax,word [arrayD + 4]    ; put the lower word of the 2nd dword in ax
于 2013-09-18T06:53:57.980 回答
1

这是一个非常简单的任务,但也有一些微小的时刻。首先,如果要将较大的数据类型转换为较小的数据类型,则应确保值足够小以适合较小的类型变量。在您的情况下,它是“单词”,并且所有数字都足够小以容纳两个字节。

第二个问题是数字的符号。他们是签名的还是未签名的?在这个例子中,只有正数,但你应该在常见的情况下说清楚。

从较小的变量大小转换为较大的变量大小非常简单,您应该使用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] 
于 2013-09-18T06:51:20.270 回答
1

我认为高级语言会对此感到悲哀。(但是谁在乎 HLL 做了什么?)您对将双字转换为单词感到紧张是完全正确的。一般来说,你不能在不丢失信息的情况下做到这一点。在这种情况下,我们可以通过检查看到双字数组中的所有三个数字都适合单词,所以你可以截断它们并称之为“转换”我猜。(可怕的任务,恕我直言)

可能给您带来更多麻烦的是寻址三种不同大小的数组。索引 0 很简单。但是对于索引 1,您需要从 中获取一个字节[arrayB + 1],将其添加到截断为来自 的单词的双字中[arrayD + 4],然后将生成的单词存储在[arrayW + 2]. 您可能会弄清楚索引 2 的外观。你说你知道如何做字节到字的部分,所以你知道如果你做 'mov ax, [ArrayB]' 它会得到 170 和 193,对吧?

如果您的代码有问题,请试一试并返回。

于 2013-09-18T03:31:57.583 回答