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

VS MASM调试found子程序ret返回Source option not available错

报错根因

Source option not available是调试器检测到程序跳转到了无对应调试符号的非法地址时触发的提示,核心原因是栈失衡导致返回地址错误,你的代码存在三个致命问题:

  • 直接用js条件跳转指令进入found子例程,没有通过call指令调用。x86体系下call执行时会自动把下一条指令的地址压栈作为返回地址,ret指令才能正确弹栈回到调用点;直接跳转进入子例程时,栈顶根本没有存入合法返回地址,执行ret时会把栈上的随机垃圾值当成目标地址弹出,直接导致程序跑飞。同样的问题也存在于jns notfound的跳转逻辑里。
  • 数组步进长度写错:你定义的slist元素是SWORD类型(16位有符号整数,占2字节),代码里硬编码add esi,4每次步进4字节,会直接跳过一半数组元素,还会触发越界内存读取。
  • 流程断裂:哪怕ret能正常返回,found/notfound执行完后也没有衔接退出逻辑,会继续执行后续内存里的非法指令。
修复方案

练习标志位跳转的场景下,完全没必要把找到/没找到的逻辑拆成独立子例程用ret返回,直接用普通跳转串起流程即可,从根源上避免栈平衡问题,修复后的完整代码如下:

; chapter -06
; find first negative number

.386
.model flat,stdcall
.stack 4096

.data
slist SWORD 0,1,2,3,-9,10,20

ExitProcess PROTO,dwExitCode:DWORD

.code

main PROC
    
    mov ecx,LENGTHOF slist
    mov esi,OFFSET slist
    mov ebx,0
L1:
    test WORD PTR [esi], 8000h  ; 直接检查16位有符号数的最高位(符号位),不额外改动寄存器
    js found
    add esi, TYPE slist         ; 用TYPE关键字自动获取SWORD的字节长度,避免硬编码错误
    LOOP L1
    jmp notfound                ; 循环遍历完未找到负数,跳转对应逻辑
found:
    mov bx,[esi]                ; 把找到的首个负数存入ebx
    jmp exit_prog
notfound:
    mov ebx,0                   ; 未找到时ebx置0
exit_prog:
    INVOKE ExitProcess,0
main endp

end main
额外优化提示
  • 你原本写的pushfd/popfd是多余操作:js判断完成后,只有当前数非负数才会走到步进数组的逻辑,此时已经不需要保留之前的标志位状态,多余的栈操作反而会增加栈失衡的风险。
  • 检查符号不需要用add ax,[esi]的方式,test指令直接按位与检查符号位即可,既不用提前给eax清零,也不会改动源操作数,执行效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:54:32