You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MASM汇编二维数组第二行降序检测代码问题排查

MASM汇编二维数组第二行降序检测错误排查

现有MASM汇编代码用于检测二维数组第二行是否按降序排列,但无论数组内容如何,始终返回"Yes",修改esi寄存器值后问题依旧,以下为原代码:

.686
.model flat, stdcall
option casemap:none

include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\masm32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includeLib C:\masm32\lib\masm32.lib

.data
    sConsoleTitle BYTE "Task", 0
    task BYTE "Check if the second row of a two-dimensional array is sorted in descending order", 0Dh, 0Ah, 0
    Arr     DWORD   4, 6, 2, 8
    RowSize = ($ - Arr)
            DWORD    9, 4, 2, 1
            DWORD    7, 3, 5, 1
            DWORD    6, 8, 1, 7
    resultText BYTE "Result: "
    row BYTE 4
    col BYTE 4
    i BYTE 0
    j BYTE 0
    exitText BYTE "Print enter to exit....", 0Dh, 0Ah, 0
    pos BYTE "Yes", 0Dh, 0Ah, 0
    negative BYTE "No", 0Dh, 0Ah, 0
    resultStr BYTE 16 DUP(' ')
    buffer BYTE 20 DUP(?), 0
    clrt BYTE 0Ah, 0Dh, 0
    tab BYTE "  ", 0
    sum DWORD 0

.code
start:
invoke SetConsoleTitle, offset sConsoleTitle
invoke StdOut, offset task

; Show array
xor ecx, ecx
mov cl, row
mov esi, 0
loop_row_1:
    push ecx
    xor ecx, ecx
    mov cl, col
    mov ebx, 0
loop_col_1:
    mov eax, Arr[esi][ebx]
    push ebx
    push ecx
    push esi
    invoke ltoa, eax, ADDR buffer
    invoke StdOut, ADDR buffer
    invoke StdOut, ADDR tab
    pop esi
    pop ecx
    pop ebx
    add ebx, TYPE Arr

    loop loop_col_1
    invoke StdOut, ADDR clrt

    add esi, RowSize

    pop ecx
    loop loop_row_1

; Check
mov esi,1
xor ecx, ecx
mov cl, col
mov ebx, 0
mov j, 0
loop_col_2:
    mov eax, Arr[esi][ebx]
    cmp eax, 0
    jle no
    add ebx, TYPE Arr
    loop loop_col_2
    invoke StdOut, ADDR clrt
yes:
    invoke StdOut, ADDR resultText
    invoke StdOut, ADDR pos
    jmp exit
no:
    invoke StdOut, ADDR resultText
    invoke StdOut, ADDR negative
exit:
    invoke StdIn, ADDR buffer, lengthof buffer
end start

核心错误点

  • 行偏移定位错误:原代码用mov esi,1定位第二行,逻辑完全错误。数组中每个元素是DWORD(4字节),第一行RowSize = ($ - Arr)计算得16字节(4个DWORD),第二行的起始偏移应为RowSize,而非1。
  • 检测逻辑偏离需求:原代码仅判断元素是否大于0(cmp eax, 0),这和"降序排列"的要求无关。降序需要依次比较相邻元素,验证前一个元素是否大于等于后一个元素。

修正后的检测逻辑代码

; Check
mov esi, RowSize  ; 正确定位到第二行的起始偏移
xor ecx, ecx
mov cl, col
dec cl            ; 4个元素仅需比较3次相邻元素
mov ebx, 0
loop_col_2:
    mov eax, Arr[esi][ebx]          ; 取当前元素
    mov edx, Arr[esi][ebx+TYPE Arr] ; 取下一个相邻元素
    cmp eax, edx                    ; 验证前一个元素是否 >= 后一个元素
    jl no                           ; 若前一个 < 后一个,直接判定为非降序
    add ebx, TYPE Arr
    loop loop_col_2
invoke StdOut, ADDR clrt
yes:
    invoke StdOut, ADDR resultText
    invoke StdOut, ADDR pos
    jmp exit
no:
    invoke StdOut, ADDR resultText
    invoke StdOut, ADDR negative
exit:
    invoke StdIn, ADDR buffer, lengthof buffer

修正说明

  1. 用RowSize作为第二行的起始偏移,确保正确定位目标行。
  2. 将循环次数改为col-1,因为n个元素仅需比较n-1次相邻元素。
  3. 新增相邻元素比较逻辑,一旦出现前一个元素小于后一个的情况,立即跳转到"No"分支,终止检测。

内容的提问来源于stack exchange,提问作者woolMe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:23:09