编写一个循环执行用户输入的程序,直到满足两个条件之一

问题描述 投票:0回答:1

我是学习 NASM 组装的新手。我不断遇到两个不同的问题。程序要么继续循环,要么在第一次输入后在满足任何条件之前停止。

我想让用户给出输入,并使程序继续循环,直到所有输入的总和大于 9 或直到用户输入 0。

section .data
    ask db 'Enter a number between 1 and 9, or 0 to exit: ', 0Ah
    ask_len equ $ - ask

section .bss
    total resb 4
    input resb 1

section .text
    global _start

_start:
    ; Initialize total to 0
    mov al, '0'
    mov [total], al

input_loop:
    ; Use SYS_WRITE to print the prompt
    mov eax, 4
    mov ebx, 1
    mov ecx, ask
    mov edx, ask_len
    int 80h

    ; Use SYS_READ to read a single character into input
    mov eax, 3
    mov ebx, 0
    mov ecx, input
    mov edx, 1
    int 80h

    ; Check if input == '0', if yes, exit the loop
    cmp byte [input], '0'
    je exit_loop

    ; Convert ASCII character to numeric value
    sub byte [input], '0'

    ; Load current total into al
    mov al, [total]

    ; Add input to al
    add al, [input]

    ; Check if result is greater than '9', if yes, exit the loop
    cmp al, '9'
    jg exit_loop

    ; Store the result back in total
    mov [total], al
    
    ; Convert the final resul
    add byte [total], '0'
    
    ; Unconditionally jump back to input_loop
    jmp input_loop

exit_loop:
    ; Use SYS_WRITE to print the total
    mov eax, 4
    mov ebx, 1
    mov ecx, [total]
    mov edx, 1
    int 80h

    ; Exit the program with code 0
    mov eax, 1
    xor ebx, ebx
    int 0x80
linux loops assembly x86 nasm
1个回答
0
投票
; Use SYS_READ to read a single character into input
mov eax, 3
mov ebx, 0
mov ecx, input
mov edx, 1
int 80h

您不应该忘记按 Enter 键获得的换行符。更好地定义

input resb 2
并通过
mov edx, 2
请求 2 个字节。您仍然在
byte [input]
处处理字节。

; Store the result back in total
mov [total], al
; Convert the final resul
add byte [total], '0'                        <<< wrong
; Unconditionally jump back to input_loop
jmp input_loop

您选择将 total 变量初始化为 character '0'。直到您将其存储回内存为止都很好。但随后您错误地添加了另一个“0”,以便将已经是字符的内容转换为字符。

; Check if result is greater than '9', if yes, exit the loop
cmp al, '9'
jg exit_loop
; Store the result back in total
mov [total], al

一旦 AL 寄存器中的结果符合条件,您立即跳转到 exit_loop,您(尝试 (1))显示 total 变量中的内容,但是您没有使用最新值更新该变量来自 AL。问题在于,IMO 认为,考虑到任务描述,这可能没问题;它肯定会避免显示两位数的最终结果。
(1) 关于显示结果,

mov ecx, [total]
从内存中获取字符,其中SYS_WRITE真正期望您提供指向该字符的指针。只需松开方括号即可。

section .data
    ask db 'Enter a number between 1 and 9, or 0 to exit: ', 0Ah
    ask_len equ $ - ask

section .bss
    total resb 4
    input resb 2

section .text
    global _start

_start:
    ; Initialize total to '0' plus a newline
    mov eax, 00000A30h

input_loop:
    mov [total], eax

    ; Use SYS_WRITE to print the prompt
    mov eax, 4
    mov ebx, 1
    mov ecx, ask
    mov edx, ask_len
    int 80h

    ; Use SYS_READ to read a single character into input
    mov eax, 3
    mov ebx, 0
    mov ecx, input
    mov edx, 2
    int 80h

    ; Check if input == '0', if yes, exit the loop
    cmp byte [input], '0'
    je exit_loop

    ; Convert ASCII character to numeric value [1,9]
    sub byte [input], '0'
    mov eax, [total]
    add al, [input]

    ; Check if result is greater than '9', if yes, exit the loop
    cmp al, '9'
    jng input_loop

exit_loop:
    ; Use SYS_WRITE to print the 1-digit total plus a newline
    mov eax, 4
    mov ebx, 1
    mov ecx, total
    mov edx, 2
    int 80h

    ; Exit the program with code 0
    mov eax, 1
    xor ebx, ebx
    int 0x80

输入: 1 输入 5 输入 2 输入 4 输入

输出:8

使用 NASM 在 Assembly 中添加 2 个输入的数字有一个非常相似的解决方案。在这里您可以学习如何显示结果(如果它可以包含 2 位数字)...

© www.soinside.com 2019 - 2024. All rights reserved.