汇编:在电脑上通过键盘输入10个学生的成绩后,依次在界面上显示:及格人数x个,不及格人数y个。 要求:提示输入10个学生成绩score,每个成绩数字之间空格隔开,键盘送入; 换行输出“10个学生成绩分别为……” 换行显示结果:及格人数x个,不及格人数y;
时间: 2024-02-11 14:10:01 浏览: 195
下面是一个 NASM 汇编代码实现:
```
global _start
section .data
pass_score db 60 ; 及格分数线
count_pass db 0 ; 及格人数计数器
count_fail db 0 ; 不及格人数计数器
score_msg db "10个学生成绩分别为:", 0
pass_msg db "及格人数:%d\n", 0
fail_msg db "不及格人数:%d\n", 0
section .bss
input_score resb 10 ; 存储学生分数的数组
section .text
_start:
; 提示用户输入成绩
mov eax, 4 ; 系统调用号 4 表示显示字符串
mov ebx, 1 ; 文件描述符 1 表示标准输出
mov ecx, input_msg ; ecx 寄存器指向字符串首地址
mov edx, input_msg_len ; 字符串长度
int 0x80 ; 调用系统调用,显示提示信息
; 读取用户输入的成绩
mov ebx, input_score ; ebx 寄存器指向数组首地址
mov ecx, 10 ; ecx 寄存器计数器初始化为 10
input_loop:
; 读入一个字符
mov eax, 3 ; 系统调用号 3 表示读取字符
mov edx, 1 ; 一次读取一个字符
int 0x80 ; 调用系统调用
cmp al, ' ' ; 检查是否是空格字符
je next_input ; 如果是空格字符,跳过
sub al, '0' ; 将字符转换为数字
mov [ebx], al ; 将数字存入数组
inc ebx ; 更新数组指针
next_input:
loop input_loop ; 继续读取下一个字符,直到读完 10 个字符
; 显示学生分数
mov eax, 4 ; 系统调用号 4 表示显示字符串
mov ebx, 1 ; 文件描述符 1 表示标准输出
mov ecx, score_msg ; ecx 寄存器指向字符串首地址
mov edx, score_msg_len ; 字符串长度
int 0x80 ; 调用系统调用,显示学生分数信息
; 通过循环计算及格人数和不及格人数
mov ecx, 10 ; ecx 寄存器计数器初始化为 10
mov ebx, input_score ; ebx 寄存器指向数组首地址
mov byte [count_pass], 0 ; 及格人数计数器初始化为 0
mov byte [count_fail], 0 ; 不及格人数计数器初始化为 0
count_loop:
; 比较分数与及格分数线
cmp [ebx], pass_score
jge pass ; 如果分数大于等于及格分数线,则跳转到 pass 标签
fail:
; 分数小于及格分数线,不及格人数计数器加一
inc byte [count_fail]
jmp next_student ; 跳转到下一位学生
pass:
; 分数大于等于及格分数线,及格人数计数器加一
inc byte [count_pass]
next_student:
; 更新数组指针,继续计算下一位学生分数
inc ebx
loop count_loop
; 显示结果
mov eax, 4 ; 系统调用号 4 表示显示字符串
mov ebx, 1 ; 文件描述符 1 表示标准输出
mov ecx, pass_msg ; ecx 寄存器指向字符串首地址
mov edx, pass_msg_len ; 字符串长度
push word [count_pass] ; 将及格人数推入栈中
call printf ; 调用 printf 函数,显示及格人数信息
mov eax, 4 ; 系统调用号 4 表示显示字符串
mov ebx, 1 ; 文件描述符 1 表示标准输出
mov ecx, fail_msg ; ecx 寄存器指向字符串首地址
mov edx, fail_msg_len ; 字符串长度
push word [count_fail] ; 将不及格人数推入栈中
call printf ; 调用 printf 函数,显示不及格人数信息
; 退出程序
mov eax, 1 ; 系统调用号 1 表示退出程序
xor ebx, ebx ; 返回值为 0
int 0x80
; printf 函数
; 参数:格式化字符串的地址和栈中的参数
; 返回值:无
printf:
push ebp ; 保存 ebp 寄存器
mov ebp, esp ; 将 ebp 寄存器指向栈顶
sub esp, 4 ; 为局部变量预留 4 字节的栈空间
mov eax, [ebp+8] ; 将格式化字符串的地址存入 eax 寄存器
mov ebx, [ebp+12] ; 将参数存入 ebx 寄存器
push ebx ; 将参数推入栈中
mov edx, [eax-4] ; 将格式化字符串的长度存入 edx 寄存器
add eax, edx ; 将格式化字符串的地址指向字符串末尾
mov ecx, edx ; 将字符串长度存入 ecx 寄存器
mov edx, 1 ; 文件描述符 1 表示标准输出
mov ebp, esp ; 将 ebp 寄存器指向栈顶
int 0x80 ; 调用系统调用,显示格式化字符串和参数
add esp, 8 ; 清空栈空间
pop ebp ; 恢复 ebp 寄存器
ret ; 返回
section .data
input_msg db "请输入10个学生成绩(用空格隔开):", 0
input_msg_len equ $-input_msg
score_msg_len equ 21 ; 10 个数字加上分隔符和换行符总共 21 个字符
```
这段程序首先定义了四个数据段:
- `.data` 段定义了及格分数线、计数器的初始值和提示信息。
- `.bss` 段定义了一个长度为 10 的数组,用于存储学生分数。
- `.text` 段包含了程序的主要逻辑。
- `printf` 函数用于格式化输出信息。
程序从 `_start` 标签处开始执行。首先通过系统调用显示提示信息,然后读取用户输入的成绩,并将其存入数组中。读入完毕后,程序通过系统调用显示学生分数信息。
接着,程序通过循环计算及格人数和不及格人数。读取一个分数后,将其与及格分数线比较,如果分数小于及格分数线,则不及格人数计数器加一;否则,及格人数计数器加一。
计算完毕后,程序通过调用 `printf` 函数格式化输出及格人数和不及格人数信息,然后退出程序。
需要注意的是,这段程序使用了 Linux 系统调用,因此只能在 Linux 环境下运行。如果需要在其他操作系统上运行,需要修改系统调用号。
阅读全文