xp967826 2024-06-09 22:28 采纳率: 50%
浏览 1

汇编代码运行和调试结果不一致

大家好,我这个Masm for Windows的汇编代码运行和调试的结果都不一样,能不能帮我看一看,十分感谢!!
该程序目的是:接收一字符串,然后分别统计其数字及英文的数量,最后用十进制表示

img

DATAS SEGMENT
    STR1 DB 'input a string :','$',0dh,0ah;提示输入字符串
    STR2 DB 0dh,0ah,'the number of numbers :','$'
    STR3 DB 0dh,0ah,'the number of letters :','$'
    STR4 DB 0dh,0ah,'the length of the string :','$';显示各项数值
    STR5 DB 100 ;准备接收100个字符.
    NUMSTR DB ? ;接收输入的字符串个数
    STR6 DB 100 DUP(?) ;开辟100字节的空间
    NUMSHU DB ?
    NUMLETTER DB ?;定义两个变量分别记录数字及字母的个数
    ;此处输入数据段代码

DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX, DATAS
    MOV DS, AX
    MOV NUMSHU, 0
    MOV NUMLETTER, 0;将数字个数和字母个数置0
    MOV DX, OFFSET STR1;取str1的地址给dx:ax
    MOV AH, 9
    INT 21H;调用bos的9h功能,显示出STR1
    MOV DX, OFFSET STR5
    MOV AH, 0ah 
    INT 21H;调用0ah号功能,将dx:ax作为地址接收键盘输入的字符
    
    MOV CL, NUMSTR;实际收到字符的个数;
    CMP CL, 0;判断实际接受字符个数是否大于0;;
    JNZ LIUC;字符个数不等于0时,跳转到liuc这个子程序
    CALL OVER;为0则结束

LIUC:
    LEA SI, STR6 ;用si寄存器存收到字符的起始地址

FIRST:
    MOV AL, [SI];将si指的内存单元里的内容转递给al寄存器
    INC SI;地址加一
    CMP AL,07h;判断字符串里单个字符是否等于07h 
    JNz SHU ;不等于07h,则跳转到判断字符是否为数字的子程序
    call xiansi;调用显示有多少数字,字母的子程序


SHU:;判断字符是否在0到9之间
    CMP AL, '0'
    JC FIRST;字符比0小,则返回到first子程序,取下一个字符
    CMP AL, ':' 
    JNC LETTERBIG ;字符比9大,跳转的letterbig子程序,判断字符是否为字母
    INC NUMSHU ;字符在0到9之间,使numshu加一
    JMP FIRST;返回first子程序,取下一个字符

LETTERBIG:;判断字符是否为大写字母
    CMP AL, 'A'
    JC FIRST ;字符比A小,则取下一个字符
    CMP AL, '[' ;
    JNC LETTERSMALL ;字符比Z大,跳转到lettersmall子程序,判断是否为小写字母
    INC NUMLETTER ;字母个数加一
    JMP FIRST;返回first子程序,取下一个字符

LETTERSMALL:;判断字符是否为小写字母
    CMP AL, 'a';
    JC FIRST ;字符比a小,取下一个字符
    CMP AL, '{' ;
    JNC FIRST ;字符比z大,取下一个字符
    INC NUMLETTER ;字母个数加一
    JMP FIRST;返回first子程序,取下一个字符
    RET

XIANSI:;显示数字,字母,字符的个数
    MOV DX, OFFSET STR2
    MOV AH, 9 
    INT 21H;调用bos的9号功能,显示str2的内容
    ;;;;SUB NUMSHU,1
    MOV AL, NUMSHU;将16进制的数转递给al寄存器
    CALL ZHUANHUAN;调用16进制转换到10进制的子程序
    
    MOV DX, OFFSET STR3
    MOV AH, 9 
    INT 21H;调用bos的9号功能,显示str3的内容
    SUB NUMLETTER,1
    MOV AL, NUMLETTER;将16进制的数转递给al寄存器
    CALL ZHUANHUAN;
    
    MOV DX, OFFSET STR4
    MOV AH, 9 
    INT 21H;调用bos的9号功能,显示str4的内容
    MOV AL, NUMSTR;将16进制的数转递给al寄存器
    CALL ZHUANHUAN;

OVER:;结束的子程序
    MOV AH, 4CH
    INT 21H

ZHUANHUAN: ;将al寄存器里16进制的数转换成10进制的数
    MOV DL, 00H 
    MOV BX, 0 
    MOV Ah, 0 ; 清除AH寄存器  
    CMP AL, 9;判断是否为一位数
    JLE SINGLE; 如果小于等于9,则跳转到SINGLE    
    MOV AH, 0 ; AH清零  
    MOV BL, 10;
    DIV BL; 将AL中的值除以10,商在AL中,余数在AH中  
    ADD AL, 30H; 将商值转换为ASCII字符  
    MOV DL, AL;将ASCII字符放入DL中  
    MOV AH, 2
    INT 21H; 调用DOS中断2号功能显示字符  
    ADD AH, 30H ; 将余数值转换为ASCII字符  
    MOV DL, AH 
    MOV AH, 2
    INT 21H ; 调用DOS中断2号功能显示字符  
    CALL OVER

SINGLE:  
    ADD AL, 30H ; 将数字转换为ASCII字符  
    MOV DL, AL  
    MOV AH, 2
    INT 21H; 调用DOS中断2号功能显示字符
    RET
    
    ;此处输入代码段代码
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START
  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-09 22:28
    关注

    引自免费微信小程序:皆我百晓生

    从你提供的代码来看,主要的问题在于程序的逻辑和DOS中断的使用上存在一些不当之处,这可能导致运行和调试结果不一致。下面我将详细分析并提供修改建议。

    主要问题点

    1. 字符范围判断错误:你的代码在判断字符是否是数字或字母时,使用了错误的比较值。
    2. ZHUANHUAN 子程序的调用问题ZHUANHUAN 子程序用于将十六进制数转换为十进制并显示,但在某些情况下,它被错误地调用或没有正确处理。
    3. XIAN 子程序调用与返回问题XIAN 子程序(实际上应该是XIANSI)的调用和返回可能存在问题,导致程序流程混乱。

    修改建议

    字符范围判断修正

    • SHU标签中,应将CMP AL, ':'更改为CMP AL, '9'
    • LETTERBIGLETTERSMALL标签中,应将CMP AL, '['更改为CMP AL, 'Z'CMP AL, '{'更改为CMP AL, 'z'

    ZHUANHUAN 子程序调用修正

    • 确保在调用ZHUANHUAN之前,AL寄存器中存放的是正确的待转换数值。
    • 移除ZHUANHUAN子程序末尾的CALL OVER语句,这会导致程序提前结束。

    代码修正示例

    以下是针对上述问题修改后的部分代码片段:

    SHU:
        CMP AL, '0'
        JB FIRST ; 小于'0'则返回
        CMP AL, '9' ; 更正为'9'
        JA LETTERBIG ; 大于'9'则跳转到LETTERBIG
        INC NUMSHU
        JMP FIRST
    
    LETTERBIG:
        CMP AL, 'A'
        JB FIRST
        CMP AL, 'Z' ; 更正为'Z'
        JA LETTERSMALL
        INC NUMLETTER
        JMP FIRST
    
    LETTERSMALL:
        CMP AL, 'a'
        JB FIRST
        CMP AL, 'z' ; 更正为'z'
        JA FIRST
        INC NUMLETTER
        JMP FIRST
    
    ZHUANHUAN:
        ;...保持其他代码不变
        ; 移除CALL OVER语句
        RET
    
    XIANSI:
        ;...保持其他代码不变
        ; 正确调用ZHUANHUAN后,直接返回,不要有额外的CALL OVER
        RET
    

    进一步检查

    • 确认NUMSTR变量是否正确地存储了输入字符串的长度。
    • 检查所有中断调用前后的寄存器状态,确保没有破坏必要的寄存器值。
    • 确保所有子程序正确返回,没有提前调用结束程序的指令。

    通过这些修改和检查,你应该能够解决运行和调试结果不一致的问题。如果还有其他具体疑问或错误,欢迎继续提问。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月9日

悬赏问题

  • ¥20 Github上传代码没有contribution和activity记录
  • ¥20 SNETCracker
  • ¥15 数学建模大赛交通流量控制
  • ¥15 为什么我安装了open3d但是在调用的时候没有报错但是什么都没有发生呢
  • ¥50 paddleocr最下面一行似乎无法识别
  • ¥15 求某类社交网络数据集
  • ¥15 靶向捕获探针方法/参考文献
  • ¥15 很抱歉出现错误word不能启动(24),如何解决?
  • ¥15 javascript下载网络图片
  • ¥15 excel中的填充效果 对应poi的哪个对象啊