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

x86汇编冒泡排序程序报错求助:缺失跳转指令及编译错误

x86汇编程序错误排查与修复

编译错误说明

在VS2022中编译时出现以下错误:

1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.targets(50,5): error MSB3721: The command "ml.exe /c /nologo /Sg /Zi /Fo"Debug\Template.obj" /Fl"Project.lst" /I "C:\irvine" /W3 /errorReport:prompt /TaTemplate.asm" exited with code 1.

该错误由代码中的语法、逻辑错误导致ml.exe编译失败,以下是具体问题分析与修复方案。

代码中的错误点

1. sortAscending过程的核心错误

  • 元素取值错误:mov eax,esi是将数组元素的内存地址存入EAX,而非元素值,正确写法应为mov eax,[esi],这是触发编译失败的直接原因之一。
  • 缺失提前退出逻辑:冒泡排序可通过交换标记提前结束排序(数组已有序时无需继续循环),原代码未实现该逻辑,且外层循环流程存在漏洞。

2. getLargest过程的错误

  • 循环边界判断错误:cmp ecx,esi将元素个数(ECX)与内存地址(ESI)直接比较,逻辑完全错误,应依赖loop指令的计数功能控制循环。
  • 输出顺序颠倒:先输出点号再输出提示语和数值,不符合正常展示逻辑,应调整为提示语→数值→点号的顺序。
  • 无符号数输出错误:使用WriteInt输出无符号数会导致异常显示(如0xFFFFFFFF会被显示为-1),需改用无符号输出指令。
  • 数组越界风险:原循环逻辑会访问数组最后一个元素的下一个内存地址,需调整循环次数避免越界。

修复后的完整代码

TITLE Sort Arrays, Version 1  (SortArrays.asm)

; 本程序遍历并
; 原地对数组进行升序
; 排序,输出每个数组的
; 最大值。
; 姓名: Kasizah
; 日期: 2022年10月19日

INCLUDE Irvine32.inc

.data
Array1  DWORD 0C0D12AFh, 00030256h, 0FFAABBCCh, 0F700F70h, 00000000h, 0E222111Fh, 0ABCDEF01h, 01234567h
Array2  DWORD 61A80000h, 024F4A37h, 0EC010203h, 0FAEEDDCCh, 2C030175h, 84728371h, 63AA5678h, 0CD454443h, 22222222h, 61B1C2D3h, 7A4E96C2h, 81002346h, 0FDB2726Eh, 65432100h, 0FFFFFFFFh

; 消息字符串
largestUnsignedS BYTE "The largest unsigned value in the array is: ",0
largestUnsignedF BYTE ".",0

.code
main PROC
    mov  esi,OFFSET Array1   ; 指向Array1的起始位置
    mov  ecx,LENGTHOF Array1 ; 获取Array1的长度
    call sortAscending       ; 对Array1排序
    ; 使用DumpMem显示排序后的数组
    mov  esi,OFFSET Array1   ; 起始偏移地址
    mov  ecx,LENGTHOF Array1 ; 元素数量
    mov  ebx,TYPE Array1     ; 双字格式
    call DumpMem
    ; 获取Array1的最大值
    mov  esi,OFFSET Array1   ; 指向Array1的起始位置
    mov  ecx,LENGTHOF Array1 ; 获取Array1的长度
    call Crlf                ; 换行
    call getLargest          ; 显示Array1的最大值
    call Crlf                ; 换行
    
    mov  esi,OFFSET Array2   ; 指向Array2的起始位置
    mov  ecx,LENGTHOF Array2 ; 获取Array2的长度
    call sortAscending       ; 对Array2排序
    ; 使用DumpMem显示排序后的数组
    mov  esi,OFFSET Array2   ; 起始偏移地址
    mov  ecx,LENGTHOF Array2 ; 元素数量
    mov  ebx,TYPE Array2     ; 双字格式
    call DumpMem
    ; 获取Array2的最大值
    mov  esi,OFFSET Array2   ; 指向Array2的起始位置
    mov  ecx,LENGTHOF Array2 ; 获取Array2的长度
    call Crlf                ; 换行
    call getLargest          ; 显示Array2的最大值
    call Crlf                ; 换行
    
    exit                     ; 退出程序
main ENDP
;-------------------------------------------------------
sortAscending PROC
;
; 使用冒泡排序算法对32位无符号整数数组进行升序排序。
; 接收参数:ESI=数组指针,ECX=数组大小
; 返回值:无
;-------------------------------------------------------
    mov  edi,esi            ; 保存数组起始指针
    dec  ecx                ; 外层循环次数为元素数-1
    outer_loop:
        push ecx                ; 保存外层循环计数
        mov  esi,edi            ; 重置ESI到数组开头
        mov  edx,0              ; 交换标记:0=未交换,1=已交换
        sort:
            mov  eax,[esi]       ; 获取当前数组元素值
            cmp  [esi+4],eax     ; 比较当前元素与下一个元素
            ja   next            ; 无符号比较:如果下一个元素更大,不交换
            xchg eax,[esi+4]     ; 否则交换两个元素
            mov  [esi],eax
            mov  edx,1           ; 标记已发生交换
        next:
            add  esi,4           ; 指针移动到下一个元素
            loop sort            ; 内层循环
            
            pop  ecx             ; 恢复外层循环计数
            cmp  edx,0           ; 判断是否发生交换
            je   quit            ; 未交换则数组已有序,提前退出
            loop outer_loop      ; 否则继续外层循环
    quit:
        ret
sortAscending ENDP
;-------------------------------------------------------
getLargest PROC
;
; 在无符号数数组中查找最大值并输出。
; 接收参数:ESI=数组指针,ECX=数组大小
; 返回:输出最大值提示与结果
;-------------------------------------------------------
    mov  eax,[esi]          ; 初始化最大值为第一个元素
    dec  ecx                ; 循环次数为元素数-1(已取第一个元素)
    sift:
        add  esi,4          ; 移动到下一个元素
        cmp  [esi],eax      ; 比较当前元素与当前最大值
        jbe  next           ; 若当前元素更小,跳过
        mov  eax,[esi]      ; 更新最大值
    next:
        loop sift           ; 继续循环
    ; 输出结果
    mov  edx,OFFSET largestUnsignedS
    call WriteString        ; 输出提示语
    call WriteHex           ; 输出无符号最大值
    mov  edx,OFFSET largestUnsignedF
    call WriteString        ; 输出点号
    ret
getLargest ENDP
END main

修复说明

  1. sortAscending修复:

    • 修正元素取值指令为mov eax,[esi]
    • 添加交换标记EDX,当内层循环无交换时直接跳转到quit退出排序,优化性能
    • 改用无符号比较指令ja,匹配数组无符号数的属性
  2. getLargest修复:

    • 移除错误的地址与数值比较逻辑,依赖loop指令控制循环次数
    • 调整输出顺序,符合正常阅读逻辑
    • 改用WriteHex输出无符号数,避免有符号数的异常显示
    • 初始化最大值为第一个元素,循环次数改为元素数-1,彻底避免数组越界

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:05:21