assembly 汇编程序中处理矩阵的程序

l7mqbcuq  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(135)

问题是我从来没有用过汇编语言。我只是想让你检查一下代码是否写得正确:)
该方案的任务是:
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,但我找到的值不正确。


的数据

ijxebb2r

ijxebb2r1#

  • 找到转置矩阵(保存到arr 2)

这里唯一的真实的错误是24处的 * arr 2 OffsetCnt * 太小,因为在第二个矩阵中向下移动一行使用了28的步长(7列 * 4字节)。
add [ESI], EAX加法指令本身并没有错,但它意味着您只能使用一次代码,并且目标矩阵为零!
定义下一个equate来替换那些基于内存的 rowCntcolCnt 变量是有意义的。定义了这些equate,MASM就可以为你做汇编时计算了:

colsA equ 6
rowsA equ 7
colsB equ rowsA
rowsB equ colsA

字符串
你不需要 iter 变量来临时存储。你可以在堆栈上保留值,但更好的解决方案是使用一个额外的寄存器,如EDX。你有很多寄存器。
你不需要 * arr 2 OffsetCnt * 变量来调整内部循环的地址。只要在堆栈上保留目标地址,一旦恢复就加4。

; Transpose matrix
  mov  edi, OFFSET arrB    ; Destination
  mov  esi, OFFSET arrA    ; Source
  mov  ecx, rowsA
OuterLoop:
  mov  edx, colsA
  push edi                 ; (1)
InnerLoop:
  mov  eax, [esi]
  add  esi, 4
  mov  [edi], eax
  add  edi, colsB * 4      ; Same as `add edi, rowsA * 4`
  dec  edx
  jnz  InnerLoop     
  pop  edi                 ; (1)
  add  edi, 4
  dec  ecx
  jnz  OuterLoop

  • 求第七个和第六个的标量积

这里被忽略的错误是第一个数组没有第7列。接下来你需要将任务的这一步应用于转置矩阵。
因为在内存中元素是相邻的,你不需要两个不同的指针寄存器。
而且,这段代码也不必要地复杂,不需要所有那些基于内存的中间变量。
在32位中,你永远不应该使用(慢)loop指令,正如我在下面的代码片段中所演示的,你甚至不需要总是使用专用的循环计数器。在这里,只要(唯一的)指针停留在数组的内存中,我就继续循环。数组的结尾是用OFFSET arrB + (colsB * rowsB * 4)计算的。

; scalar product of 7th and 6th columns
  mov  ebx, OFFSET arrB + 20  ; 6th column on the 1st row
  xor  ecx, ecx               ; scalarProd
LOOP3:
  mov  eax, [ebx]
  imul eax, [ebx + 4]
  add  ecx, eax
  add  ebx, colsB * 4         ; Same as `add ebx, rowsA * 4`
  cmp  ebx, OFFSET arrB + (colsB * rowsB * 4)
  jb   LOOP3
  mov  scalarProd, ecx

  • 找到满足期望(a[i] <= B(-22))的第4行元素的数量和总和||a[i]>c(81))

目前,你正在处理第一个数组(源).我相信这将是更有意义的任务的最后一步应用到第二个数组(目标).事实上,任务的中间步骤,通过提到第7列,已经被迫使用第二个数组,至少对我来说,指向这个方向.
你编码的逻辑可以工作,但是过于复杂了。而且值81被错误地处理了!
不使用汇总变量 compRes,看看下面的代码是如何在不满足条件的情况下跳过的。

; amount and sum of the elements of 4th row, that meets expectation (a[i] <= b(-22) || a[i]>c(81))

  mov  ebx, arrB + ((colsB * 4) * 3)  ; Address of the 4th row
  xor  ecx, ecx                       ; condSum
LOOP4:
  mov  eax, [ebx]
  cmp  eax, varb
  jle  .OK
  cmp  eax, varc
  jng  .NOK                           ; Skip if [-21,81]
.OK:
  inc  condCnt
  add  ecx, eax
.NOK:
  add  ebx, 4
  cmp  ebx, arrB + ((colsB * 4) * 4)  ; Address of the 5th row
  jb   LOOP4
  mov  condSum, ecx

相关问题