问题是我从来没有用过汇编语言。我只是想让你检查一下代码是否写得正确:)
该方案的任务是:
1.找到转置矩阵(保存到arr 2)
1.求第七个和第六个的标量积
1.找到第4行元素的数量和总和,满足期望(a[i] <= b(-22) || a[i]>c(81)
)
.586P
.MODEL FLAT, STDCALL
_DATA SEGMENT
arr1 DD -79, 59, 59, 93, -79, 84
DD -51, 43, -50, -94, 23, 70
DD -44, 97, -66, -17, 100, 82
DD -83, 76, 1, 55, -20, -34
DD -11, -51, -50, 55, -80, -28
DD 58, -60, 30, 60, 90, -46
DD 20, 82, -4, -93, -75, 35
arr2 DD 0, 0, 0, 0, 0, 0, 0
DD 0, 0, 0, 0, 0, 0, 0
DD 0, 0, 0, 0, 0, 0, 0
DD 0, 0, 0, 0, 0, 0, 0
DD 0, 0, 0, 0, 0, 0, 0
DD 0, 0, 0, 0, 0, 0, 0
rowCnt DD 7
colCnt DD 6
iter DD 0
arr1Offset DD 32
arr2Offset DD 24
arr2OffsetCnt DD 0
scalarProd SDWORD 0
var1 SDWORD 0
var2 SDWORD 0
varb DD -22
varc DD 81
condCnt DD 0
condSum SDWORD 0
compRes SDWORD 0
check SDWORD 0
_DATA ENDS
_TEXT SEGMENT
START:
; Transpose matrix
mov ECX, rowCnt
lea EBX, arr1
LOOP1:
mov iter, ECX
mov ECX, colCnt
lea ESI, arr2
add ESI, arr2OffsetCnt
LOOP2:
mov EAX, [EBX]
add [ESI], EAX
add EBX, 4
add ESI, arr2Offset
loop LOOP2
mov ECX, iter
add arr2OffsetCnt, 4
loop LOOP1
; scalar product of 7th and 6th columns
lea EBX, arr1
add EBX, 24
lea ESI, arr1
add ESI, 20
mov ECX, rowCnt
LOOP3:
mov EAX, [EBX]
mov var1, EAX
mov EAX, [ESI]
mov var2, EAX
mov EAX, var1
imul EAX, var2
add scalarProd, EAX
add EBX, 24
add ESI, 24
loop LOOP3
;amount and sum of the elements of 4th row, that meets expectation (a[i] <= b(-22) || a[i]>c(81))
lea EBX, arr1
add EBX, 72
mov ECX, 6
LOOP4:
mov compRes, 0
mov EAX, [EBX]
mov check, EAX
CMP EAX, varb
jg C1
mov compRes, 1
C1:
CMP EAX, varc
jl C2
mov compRes, 1
C2:
mov EAX, compRes
CMP EAX, 1
jne C3
inc condCnt
mov EAX, condSum
add EAX, [EBX]
mov condSum, EAX
C3:
add EBX, 4
loop LOOP4
RET
_TEXT ENDS
END START
字符串
我试图在内存中找到矩阵arr1和arr2,但我找到的值不正确。
的数据
1条答案
按热度按时间ijxebb2r1#
这里唯一的真实的错误是24处的 * arr 2 OffsetCnt * 太小,因为在第二个矩阵中向下移动一行使用了28的步长(7列 * 4字节)。
add [ESI], EAX
加法指令本身并没有错,但它意味着您只能使用一次代码,并且目标矩阵为零!定义下一个equate来替换那些基于内存的 rowCnt 和 colCnt 变量是有意义的。定义了这些equate,MASM就可以为你做汇编时计算了:
字符串
你不需要 iter 变量来临时存储。你可以在堆栈上保留值,但更好的解决方案是使用一个额外的寄存器,如EDX。你有很多寄存器。
你不需要 * arr 2 OffsetCnt * 变量来调整内部循环的地址。只要在堆栈上保留目标地址,一旦恢复就加4。
型
这里被忽略的错误是第一个数组没有第7列。接下来你需要将任务的这一步应用于转置矩阵。
因为在内存中元素是相邻的,你不需要两个不同的指针寄存器。
而且,这段代码也不必要地复杂,不需要所有那些基于内存的中间变量。
在32位中,你永远不应该使用(慢)
loop
指令,正如我在下面的代码片段中所演示的,你甚至不需要总是使用专用的循环计数器。在这里,只要(唯一的)指针停留在数组的内存中,我就继续循环。数组的结尾是用OFFSET arrB + (colsB * rowsB * 4)
计算的。型
目前,你正在处理第一个数组(源).我相信这将是更有意义的任务的最后一步应用到第二个数组(目标).事实上,任务的中间步骤,通过提到第7列,已经被迫使用第二个数组,至少对我来说,指向这个方向.
你编码的逻辑可以工作,但是过于复杂了。而且值81被错误地处理了!
不使用汇总变量 compRes,看看下面的代码是如何在不满足条件的情况下跳过的。
型