masm汇编找100以内素数并求和红色输出

汇编课设暴力版

要求

求 100 以内的素数。(1)用筛法求出这些素数。(2)在屏幕上显示出求素数的动态过程(在屏幕上先显示出 100 以内的所有数, 再动态地删去不符合要求的数,删除的过程要明显)。(3)计算这些素数的平均值(取整,四舍五入),以十进制形式输出,并让该值以红色显示。(4)数据的输入和结果的输出都要有必要的提示,且提示独占一行。(5)要使用到子程序。

暴力找因数版代码masm

DATAS SEGMENT
    strsum db 'xxxx$'
	sum dw ?
    temp db ?
    ans db 300 dup(?)
    outsum db 00h
DATAS ENDS
 
STACKS SEGMENT
    
STACKS ENDS
 
CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    mov ax, datas
    mov ds, ax
    mov ax, 0b800h
    mov es, ax ; 保存显存的段地址
    mov si, 0000H ; 数据段偏移地址
    mov di, 21*160 ; 显存偏移地址
    call MAIN
MAIN proc near
	XOR bx,bx
    XOR ax,ax
	mov sum,BX
    mov BL, 2        ; save i(that is the dividend)
    mov BH, 2        ; save j(that is the divider)
    mov CL, 1        ; save flag(1 represent isPrime, 0 represent isNotPrime)
ISPRIME:
    cmp BL,100       ; check if need to end the program
    je STOP          ; end the program
    cmp BL,BH        ; check if divider reach to dividend iteself
    je ISCANPRINT    ; judge if can print
    XOR AX,AX        ; empty AX
    MOV AL,BL        ; move dividend to AL
    DIV BH           ; AL%BH=AH remainder stored in AH
    cmp AH,0         ; Is there any exception
    je NOTPRIME      ; if AH stores 0, that means the value stored in BL is not prime
    inc BH           ; increase the divider
    jmp ISPRIME      ; turn to the beginning and loop
ISCANPRINT:
    cmp CL,1         ; check flag
    je PRINT         ; print the value
    mov BH,2         ; if not prime, divider begin again at 2 
    mov CL,1         ; reset flag
    jmp ISPRIME      ; turn to the beginning and loop
PRINT: 
    XOR BH,BH        ; empty BH
    add sum,BX
    mov AX,BX        ; move value to AX
    call PRINTNUMBER ; print the number
 
NOTPRIME:
    inc BL           ; increase dividend
    mov CL, 0        ; set flag
    jmp ISCANPRINT   ; turn to judge
STOP:
    mov di,22*160    ; println
    call PRINTSTR
    mov di,23*160
    mov outsum,01h
    mov AX,sum
    call PRINTNUMBER
    mov ah,01h
    int 21h
    MOV  ah,4CH
    int  21H
    ret
MAIN endp

OUTNORM proc near	; print color character
    push ax
    mov al,temp
    cmp outsum,01h
    je RED
    mov ah,00000111B
    jmp continue
RED:
    mov ah,00100100B
continue:
    mov es:[di],ax
    add di,02h
    pop ax
    ret
OUTNORM endp

PRINTSTR proc near  ; print'sum'
    push ax
    push bx
    push cx
    push dx
    XOR dx,dx
    XOR ax,ax

    mov dl,'s'
    mov temp,dl
    call OUTNORM
    ;mov ah,2            
    ;int 21h
    mov dl,'u'
    mov temp,dl
    call OUTNORM
    ;mov ah,2            
    ;int 21h 
    mov dl,'m'
    mov temp,dl
    call OUTNORM
    ;mov ah,2            
    ;int 21h   
    pop dx
    pop cx
    pop bx
    pop ax
    ret
PRINTSTR endp

PRINTNUMBER proc near
    push ax
    push bx
    push cx
    push dx
 
    
    mov bx,10
    mov cx,0
 
PUSHTOSTACK:
    mov dx,0
    div bx
    
    push dx
    inc cx
    
    cmp ax,0
    jz POPFROMSTACK
    
    jmp PUSHTOSTACK
    
POPFROMSTACK:
    pop dx
    add dl,30h         ; change ASCII to real number
    mov temp,dl
    call OUTNORM
    ;mov ah,2            
    ;int 21h
           
    loop POPFROMSTACK
    
    pop dx
    pop cx
    pop bx
    pop ax
    mov temp,' '        ; print an empty space
    call OUTNORM
    ;mov AH,2
    ;mov DL,0
    ;int 21h
    ret
PRINTNUMBER endp


CODES ENDS
    END START


采用往显存里塞入字符和属性的办法输出带颜色字符。具体输出原理参见https://www.jianshu.com/p/450594ab3ca8。
效果:
在这里插入图片描述

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是masm汇编语言 x86 32位体系结构的代码,用于实现任意两个20位以内十进制数求和并显示结果: ```asm .386 .model flat, stdcall option casemap:none include \masm32\include\msvcrt.inc includelib \masm32\lib\msvcrt.lib .data num1 db 21 dup(?) ; 第一个数,最大为20位 num2 db 21 dup(?) ; 第二个数,最大为20位 sum db 22 dup(?) ; 存放两数之和,最大为21位 nl db 10 ; 换行符 .code _start: ; 读取num1 push offset num1 ; 存放输入值的内存地址 push 20 ; 输入值的最大长度 push offset stdin ; 文件句柄:标准输入 call _fgetws ; 调用fgetws函数,读取标准输入 add esp, 12 ; 清空栈 ; 读取num2 push offset num2 ; 存放输入值的内存地址 push 20 ; 输入值的最大长度 push offset stdin ; 文件句柄:标准输入 call _fgetws ; 调用fgetws函数,读取标准输入 add esp, 12 ; 清空栈 ; 将num1和num2转换为十进制整数 lea eax, num1 ; 将num1的地址存入eax push eax ; 将num1的地址存入栈 call ascii_to_int ; 调用ascii_to_int函数,将num1转换为十进制整数 push eax ; 将num1的值存入栈 lea eax, num2 ; 将num2的地址存入eax push eax ; 将num2的地址存入栈 call ascii_to_int ; 调用ascii_to_int函数,将num2转换为十进制整数 add eax, [esp + 4] ; 将num1和num2的和存入eax add esp, 8 ; 清空栈 ; 将和转换为ASCII码 push eax ; 将和存入栈 lea eax, sum ; 将sum的地址存入eax call int_to_ascii ; 调用int_to_ascii函数,将和转换为ASCII码 add esp, 4 ; 清空栈 ; 输出和 push offset sum ; 存放输出值的内存地址 push offset stdout ; 文件句柄:标准输出 call _fputws ; 调用fputws函数,输出到标准输出 add esp, 8 ; 清空栈 ; 输出换行符 push offset nl ; 存放输出值的内存地址 push offset stdout ; 文件句柄:标准输出 call _fputws ; 调用fputws函数,输出到标准输出 add esp, 8 ; 清空栈 ; 退出程序 push 0 ; 返回值:0 call _exit ; 调用exit函数,退出程序 ; 将ASCII码转换为十进制整数 ; 输入: ; eax - 存放ASCII码的内存地址 ; 输出: ; eax - 十进制整数 ascii_to_int: push ebx ; 用ebx存放结果 push edx ; 用edx存放位权 xor ebx, ebx ; ebx清零 xor edx, edx ; edx清零 .loop: movzx ecx, byte ptr [eax] ; 将ASCII码转换为整数 cmp ecx, 0x0A ; 判断是否到达数字末尾 je .exit ; 如果到达数字末尾,跳出循环 imul edx, edx, 10 ; 计算当前位数的位权 add ebx, ecx ; 将当前位数的值累加到结果中 inc eax ; 指向下一个数字 jmp .loop ; 继续循环 .exit: mov eax, ebx ; 将结果存入eax add esp, 8 ; 清空栈 ret ; 返回 ; 将十进制整数转换为ASCII码 ; 输入: ; eax - 十进制整数 ; 输出: ; eax - 存放ASCII码的内存地址 int_to_ascii: push esi ; 用esi存放结果 push ecx ; 用ecx存放当前位的ASCII码 push edx ; 用edx存放当前位数 mov esi, eax ; 将十进制整数存入esi lea eax, [esp + 12] ; 将存放输出值的内存地址存入eax mov byte ptr [eax], 0 ; 在末尾处添加字符串结束标志 .loop: xor edx, edx ; edx清零 div dword ptr [esp + 12] ; 将esi除以10,余数存入edx,商存入esi add dl, '0' ; 将余数转换为ASCII码 mov byte ptr [eax], dl ; 将ASCII码存入内存 dec eax ; 指向下一个内存地址 inc dword ptr [esp + 12] ; 增加当前位数的值 test esi, esi ; 判断商是否已经为0 jnz .loop ; 如果商不为0,则继续循环 mov eax, [esp + 4] ; 将存放输出值的内存地址存入eax add esp, 12 ; 清空栈 ret ; 返回 ``` 这段代码使用了 `fgetws` 和 `fputws` 函数来读取用户输入和输出结果,同时还包含了两个子函数 `ascii_to_int` 和 `int_to_ascii`,用于将ASCII码转换为十进制整数和将十进制整数转换为ASCII码。你可以将上述代码保存到一个文件中(例如 `sum.asm`),然后使用masm汇编器将其转换为可执行文件,例如: ``` > ml /c /coff sum.asm > link /subsystem:console sum.obj msvcrt.lib ``` 然后运行可执行文件即可开始使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值