assembly 如何在汇编中检查二维数组的第二行是否按降序排序

velaa5lx  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(130)

任务是:检查二维数组的第二行是否按降序排序。我需要用汇编masm来做这件事。代码如下:

  1. .686
  2. .model flat, stdcall
  3. option casemap:none
  4. include C:\masm32\include\windows.inc
  5. include C:\masm32\include\user32.inc
  6. include C:\masm32\include\kernel32.inc
  7. include C:\masm32\include\masm32.inc
  8. includelib C:\masm32\lib\user32.lib
  9. includelib C:\masm32\lib\kernel32.lib
  10. includeLib C:\masm32\lib\masm32.lib
  11. .data
  12. sConsoleTitle BYTE "Task", 0
  13. task BYTE "Check if the second row of a two-dimensional array is sorted in descending order", 0Dh, 0Ah, 0
  14. Arr DWORD 4, 6, 2, 8
  15. RowSize = ($ - Arr)
  16. DWORD 9, 4, 2, 1
  17. DWORD 7, 3, 5, 1
  18. DWORD 6, 8, 1, 7
  19. resultText BYTE "Result: "
  20. row BYTE 4
  21. col BYTE 4
  22. i BYTE 0
  23. j BYTE 0
  24. exitText BYTE "Print enter to exit....", 0Dh, 0Ah, 0
  25. pos BYTE "Yes", 0Dh, 0Ah, 0
  26. negative BYTE "No", 0Dh, 0Ah, 0
  27. resultStr BYTE 16 DUP(' ')
  28. buffer BYTE 20 DUP(?), 0
  29. clrt BYTE 0Ah, 0Dh, 0
  30. tab BYTE " ", 0
  31. sum DWORD 0
  32. .code
  33. start:
  34. invoke SetConsoleTitle, offset sConsoleTitle
  35. invoke StdOut, offset task
  36. ; Show array
  37. xor ecx, ecx
  38. mov cl, row
  39. mov esi, 0
  40. loop_row_1:
  41. push ecx
  42. xor ecx, ecx
  43. mov cl, col
  44. mov ebx, 0
  45. loop_col_1:
  46. mov eax, Arr[esi][ebx]
  47. push ebx
  48. push ecx
  49. push esi
  50. invoke ltoa, eax, ADDR buffer
  51. invoke StdOut, ADDR buffer
  52. invoke StdOut, ADDR tab
  53. pop esi
  54. pop ecx
  55. pop ebx
  56. add ebx, TYPE Arr
  57. loop loop_col_1
  58. invoke StdOut, ADDR clrt
  59. add esi, RowSize
  60. pop ecx
  61. loop loop_row_1
  62. ; Check
  63. mov esi,1
  64. xor ecx, ecx
  65. mov cl, col
  66. mov ebx, 0
  67. mov j, 0
  68. loop_col_2:
  69. mov eax, Arr[esi][ebx]
  70. cmp eax, 0
  71. jle no
  72. add ebx, TYPE Arr
  73. loop loop_col_2
  74. invoke StdOut, ADDR clrt
  75. yes:
  76. invoke StdOut, ADDR resultText
  77. invoke StdOut, ADDR pos
  78. jmp exit
  79. no:
  80. invoke StdOut, ADDR resultText
  81. invoke StdOut, ADDR negative
  82. exit:
  83. invoke StdIn, ADDR buffer, lengthof buffer
  84. end start

为什么我总是得到肯定的答案,顺便说一下,当我把 esi 寄存器的值更改为另一个值时(这个寄存器负责检查哪个字符串)。我不知道我做错了什么。(实际上,也许我做了一些关于寄存器的工作,但我有一个例子,它几乎与我的任务相同,我写的代码就像这个例子一样,但问题仍然存在)

6vl6ewon

6vl6ewon1#

你的二维矩阵是按顺序排列的。因此,您需要检查的行的元素将彼此相邻,并且将存储在内存中的连续双字中。您所需要的只是一个指向相关行开始的简单指针。行号从0开始,公式为:
RowAddress = ArrayAddress + Row * RowSize

  1. mov ebx, OFFSET Arr + 1 * RowSize ; Row = 1 for the second row

找出这一行是否按降序排序的任务转化为编写一个循环,只要第一个值大于或等于第二个,只要可以进行比较,就每2个相邻的双字进行比较,因为如果你在数组中有4列,最可能的成对比较是3。

  1. mov ebx, OFFSET Arr + RowSize ; Start of 2nd row
  2. movzx ecx, col
  3. dec ecx ; Number of required comparisons
  4. More:
  5. mov eax, [ebx]
  6. cmp eax, [ebx + 4]
  7. jl No
  8. add ebx, 4
  9. dec ecx
  10. jnz More
  11. Yes:

少用一个寄存器的另一种方法,当指针到达该行的最后一个元素时即停止:

  1. mov ebx, OFFSET Arr + RowSize ; Start of 2nd row
  2. More:
  3. mov eax, [ebx]
  4. cmp eax, [ebx + 4]
  5. jl No
  6. add ebx, 4
  7. cmp ebx, OFFSET Arr + RowSize + RowSize - 4 ; Address last element of 2nd row
  8. jb More
  9. Yes:

另一种避免两次阅读同一数据的方法是:

  1. mov ebx, OFFSET Arr + RowSize ; Start of 2nd row
  2. mov edx, [ebx]
  3. More:
  4. add ebx, 4
  5. mov eax, edx
  6. mov edx, [ebx]
  7. cmp eax, edx
  8. jl No
  9. cmp ebx, OFFSET Arr + RowSize + RowSize - 4 ; Address last element of 2nd row
  10. jb More
  11. Yes:
展开查看全部

相关问题