May*_*aya 2 arrays x86 assembly
我必须添加两个 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
Run Code Online (Sandbox Code Playgroud)
但这是 a2 和 a1 的所有元素的总和。如何逐行、逐列添加它们?我想在另一个一维数组中显示每行的总和结果(列相同)。
这
a1 WORD 1,2,3
WORD 4,2,3
WORD 1,4,3
Run Code Online (Sandbox Code Playgroud)
将编译为字节(十六进制):
01 00 02 00 03 00 04 00 02 00 03 00 01 00 04 00 03 00
Run Code Online (Sandbox Code Playgroud)
内存是按字节寻址的,所以如果你找到上面的每个元素,并计算它与第一个元素的位移(第一个元素位移了 0 个字节,即它的地址是a1+0),你应该看到一个模式,如何计算位移特定的 [y][x] 元素(x 是列号 0-2,y 是行号 0-2...如果你决定这样做,这取决于你,什么是列/行,但通常人们倾向于考虑内存中的连续元素为“一行”)。
注意基本类型字节大小,您以各种方式将其混合在一起,重新阅读一些课程/教程,了解 qword/dword/word/byte 有何不同,以及如何调整指令以使用正确的内存大小,以及如何正确计算地址(以及地址的大小eax以及如何使用其中较小的部分)。
如果您自己无法解决:
位移 = (y * 3 + x) * 2 => *2 因为元素是
word,每个占用两个字节。y * 3 因为单行有 3 个元素长。
在 ASM 指令中可以实现例如...
如果 [x,y] 是 [eax,ebx],则此计算可以如下完成
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。
现在,如果您知道如何计算特定元素的地址,则可以在每个元素加载之前循环执行所有计算,或者只在 head 中计算地址的差异并编写第一个元素的地址计算(行的开头) /column),然后mov+ 2x add,对接下来的两个元素进行硬编码偏移(为 3 个元素制作循环比编写没有循环的展开代码更麻烦),并对所有三列/行重复此操作并存储结果。
顺便说一句,那call DumpRegs......没有产生您所期望的结果?调试代码的方式有点乏味,可能值得花一些时间让调试器工作。
我无法帮助自己,但还是写了它,因为它是一段很有趣的短代码,但如果你只是复制它,而不是把它剖析成原子并完全理解它是如何工作的,你以后会后悔的):
column_sums: DW 0, 0, 0
row_sums: DW 0, 0, 0
...
; columns sums
lea esi,[a3] ; already summed elements of a1 + a2
lea edi,[column_sums]
mov ecx,3 ; three columns to sum
sum_column:
mov ax,[esi] ; first element of column
add ax,[esi+6] ; 1 line under first
add ax,[esi+12] ; 2 lines under
mov [edi],ax ; store result
add esi,2 ; next column, first element
add edi,2 ; next result
dec ecx
jnz sum_column
; rows sums
lea esi,[a3] ; already summed elements of a1 + a2
lea edi,[row_sums]
mov ecx,3 ; three rows to sum
sum_row:
mov ax,[esi] ; first element of row
add ax,[esi+2] ; +1 column
add ax,[esi+4] ; +2 column
mov [edi],ax ; store result
add esi,6 ; next row, first element
add edi,2 ; next result
dec ecx
jnz sum_row
...
Run Code Online (Sandbox Code Playgroud)
(没有调试它,所以可能会出现错误,再加上这期望 a3 包含正确的元素和,而您的原始代码不会产生这些元素和,所以您必须先修复它......这段代码确实包含很多提示,如何修复原版的每个问题)
现在,我为夺走了你写这篇文章的乐趣而感到内疚……没关系,我相信你可以找到更多的任务来练习这一点。问题是你是否掌握了它的原理。如果没有,请询问哪一部分令人困惑以及您目前如何理解它。