在Assembly(x86)中添加2D数组

时间:2017-03-27 17:41:58

标签: arrays assembly x86

我必须添加两个3 * 3的单词数组并将结果存储在另一个数组中。这是我的代码:

.data 
a1 WORD 1,2,3
   WORD 4,2,3
   WORD 1,4,3

a2 WORD 4, 3, 8
   WORD 5, 6, 8
   WORD 4, 8, 9

a3 WORD DUP 9(0)
.code
main PROC
    mov eax,0;
    mov ebx,0;
    mov ecx,0;
    mov edx,0;
    mov edi,0;
    mov esi,0;
    mov edi,offset a1
    mov esi,offset a2
    mov ebx, offset a3
    mov ecx,LENGTHOF a2

    LOOP:
    mov eax,[esi]
    add eax,[edi]
    mov [ebx], eax
    inc ebx
    inc esi
    inc edi

    call DumpRegs
    loop LOOP

    exit
main ENDP

END main

但这总结了a2和a1的所有元素。如何逐行和逐列添加它们?我想在另一个一维数组中显示每行总和的结果(列相同)。

1 个答案:

答案 0 :(得分:1)

a1 WORD 1,2,3
   WORD 4,2,3
   WORD 1,4,3

将编译为字节(以hexa为单位):

01 00 02 00 03 00 04 00 02 00 03 00 01 00 04 00 03 00

内存可以按字节寻址,所以如果你找到之上的每个元素,并计算它与第一个元素的位移(第一个位移0字节,即它的地址是{{1 }},你应该看到一个模式,如何计算特定[y] [x]元素的位移(x是列号0-2,y是行号0-2 ......如果你这样决定,它就是了对你来说,什么是列/行,但通常人们倾向于认为内存中的连续元素是“一行”。)

注意字节大小的基本类型,你可以在各个方面将它混合在一起,重读一些有关qword / dword / word / byte如何不同的课程/教程以及如何调整指令以使用正确的内存大小,以及如何正确计算地址(以及a1+0的大小以及如何使用它的较小部分)。

如果您无法自行计算:

  

位移=(y * 3 + x)* 2 => * 2因为元素是eax,每个占用两个字节。 y * 3因为单行长3个元素。

在可能实现的ASM指令中......

  

如果[x,y]是[eax,ebx],则此计算可以word |进行。 lea esi,[ebx+ebx*2] ; esi = y*3 | lea esi,[esi+eax] ; esi = y*3+x

现在,如果您知道如何计算特定元素的地址,您可以在每个元素加载之前循环执行所有计算,或者只是在头部计算地址的差异并写入第一个元素的地址计算(行/列的开始)然后mov ax,[a1+esi*2] ; loads [x,y] element from a1 + 2x mov使用下面两个元素的硬编码偏移量(为3个元素创建循环比编写没有循环的展开代码更麻烦),并重复此操作对于所有三列/行并存储结果。

顺便说一下,add ...没有产生你的期望?调试代码有点乏味,可能值得花一点时间让调试器工作。

无法帮助我自己,但写下它,因为它是如此有趣的短片代码,但你会后悔它,如果你只是复制它,而不是将其解剖为原子并完全理解它是如何工作的):

call DumpRegs

(没有调试它,所以错误是可能的,加上这个期望a3包含正确的元素总和,原始代码不会产生,所以你必须先修复它...这段代码确实包含很多提示,如何解决原始的每个问题)

现在我为从你这里写下这个乐趣而感到愧疚...没关系,我相信你可以找到更多的任务来练习这个。问题是,你是否掌握了它的原则。如果没有,请询​​问哪个部分令人困惑以及您目前如何理解它。