【汇编】子程序设计

【汇编】子程序设计

题目

实现十次循环,输入三角形三条边用子程序判断能否构成三角形,能构成输出“Y”,不能输出“N”。

代码

.686
.model flat, stdcall
option casemap :none

include     windows.inc
include     kernel32.inc
include     user32.inc
include     masm32.inc
includelib  kernel32.lib
includelib  user32.lib
includelib  masm32.lib

.data
    loopPrompt      db "第", 0
    ; 0dh 对应回车符(Carriage Return),作用是将光标移到当前行的开头
    ; 0ah 对应换行符(Line Feed),作用是将光标移到下一行
    loopPrompt2     db "次循环", 0dh, 0ah, 0                ; loopPrompt2包含回车换行
    numBuffer       db 10 dup(0)                            ; 用于存储数字转换后的字符串

    prompt1         db "请输入第一条边的长度: ", 0
    prompt2         db "请输入第二条边的长度: ", 0
    prompt3         db "请输入第三条边的长度: ", 0

    resultY         db "Y", 0
    resultN         db "N", 0

    CRLF            db 13, 10, 0                            ; 回车换行
    buffer          db 256 dup(0)                           ; 输入缓冲区,支持多位数
    count           dd 1                                    ; 循环次数
   
    ; 存储三条边
    sideA           dd 0
    sideB           dd 0
    sideC           dd 0

.code
start:
again:
    ;输出第x次循环
    invoke          dwtoa, count, addr numBuffer 
    invoke          StdOut, addr loopPrompt
    invoke          StdOut, addr numBuffer
    invoke          StdOut, addr loopPrompt2 

    ; 输入第一条边
    invoke          StdOut, addr prompt1
    invoke          StdIn, addr buffer, 255
    invoke          atodw, addr buffer
    mov             sideA, eax
    
    ; 输入第二条边
    invoke          StdOut, addr prompt2
    invoke          StdIn, addr buffer, 255
    invoke          atodw, addr buffer
    mov             sideB, eax
    
    ; 输入第三条边
    invoke          StdOut, addr prompt3
    invoke          StdIn, addr buffer, 255
    invoke          atodw, addr buffer
    mov             sideC, eax
    
    ; 调用判断子程序
    call            CheckTriangle
    
    ; 输出结果
    ; eax=1,输出Y,再continue
    cmp             eax, 1
    je              outputY
    
    ; 否则,输出N,再continue
    invoke          StdOut, addr resultN
    jmp             continue
    
outputY:
    invoke          StdOut, addr resultY
    
continue:
    ; 输出换行
    invoke          StdOut, addr CRLF
    
    ; 循环控制
    inc             count
    cmp             count, 11
    jne             again
    
    ; 程序结束
    invoke          ExitProcess, 0

; 子程序: 判断三边能否构成三角形
; 输入: 内存变量sideA, sideB, sideC
; 输出: eax=1(能构成), eax=0(不能构成)
CheckTriangle proc
    ; 轮换检查
    mov             eax, sideA
    add             eax, sideB
    cmp             eax, sideC
    jle             not_triangle
    
    mov             eax, sideA
    add             eax, sideC
    cmp             eax, sideB
    jle             not_triangle
    
    mov             eax, sideB
    add             eax, sideC
    cmp             eax, sideA
    jle             not_triangle
    
    ; 能构成三角形
    mov             eax, 1
    ret
    
not_triangle:
    ; 不能构成三角形
    mov             eax, 0
    ret
CheckTriangle endp

end start

思路

首先在数据段声明三个双字变量sideAsideBsideC用于存储三边长。这是因为初始尝试使用eaxebxecx寄存器存储时,发现eax常作为 WinAPI 返回值寄存器,ecx会被短指令用作计数器,容易发生内容覆盖导致错误,故改用数据段变量存储。

程序通过 count 变量控制循环次数,其初始值为1,每次循环结束后自增,当count等于11时跳出循环,从而实现恰好10次循环。

每次循环的流程为:

① 输出“第x次循环”提示(x为当前count值),这需要调用dwtoa函数将count的数值转换为ASCII 字符后才能输出;

② 依次通过Console输出“请输入第一条边的长度:”“请输入第二条边的长度:”“请输入第三条边的长度:”提示,使用StdIn从Console读取用户输入的三边长字符串,再经atodw转换为整数后分别存入sideAsideBsideC

③ 调用CheckTriangle子程序进行判断:该子程序对三边进行轮换检查,若存在某两边之和不大于第三边的情况,就跳转到not_triangle标签并给eax赋值0,否则给eax赋值1,最后通过RET指令返回;

④ 根据子程序返回的eax值输出结果;若eax为1则输出“Y”,否则输出“N”。

posted @ 2025-09-29 00:34  AKgrid  阅读(0)  评论(0)    收藏  举报