Win32汇编备份--循环结构

循环结构

  1. 输入若干整数,统计正数与负数和。
    运行后若输入:1 -2 3 -4
    则结果输出:正数和为:4 负数和为:-6
    请在;/和;/之间编写程序。
.386				;选择的处理器
.model flat, stdcall		;存储模型,Win32程序只能用平展(flat)模型
option casemap:none		;指明标识符大小写敏感
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg	;C语言printf函数原型声明
.data				;⑤数据段
szFmt  	BYTE	'正数和为:%d 负数和为:%d',0
 ;*【*/
include kernel32.inc
includelib kernel32.lib
infmt BYTE '%d',0
x SDWORD ?
anw_1 SDWORD 0
anw_2 SDWORD 0
.code
start:
invoke scanf,ADDR infmt,ADDR x
.WHILE EAX==1
.IF x<0
MOV EBX,anw_1
ADD EBX,x
MOV anw_1,EBX
.ELSEIF x>=0
MOV EBX,anw_2
ADD EBX,x
MOV anw_2,EBX
.ENDIF
invoke scanf,ADDR infmt,ADDR x
.ENDW
invoke printf,ADDR szFmt,anw_2,anw_1
invoke ExitProcess,0
 ;*】*/
end start 
  1. 键盘输入若干实数,求其和。
    运行后若输入:
    1.2 2.3 3.4
    则结果输出:
    6.9
    请在;/和;/之间编写程序。
.386
.model flat, stdcall
include kernel32.inc
includelib kernel32.lib
includelib	msvcrt.lib				;引用C库文件
printf PROTO C:ptr sbyte,:vararg	;C语言printf函数原型声明
scanf PROTO C:ptr sbyte,:vararg	;C语言scanf函数原型声明
option casemap :none 
 ;*【*/
.data
infmt BYTE '%lf',0
outfmt BYTE '%g',13,10,0
x QWORD ?
anw QWORD 0
.code
start:
FLD anw
invoke scanf,ADDR infmt,ADDR x
.WHILE EAX==1
FADD x
invoke scanf,ADDR infmt,ADDR x
.ENDW
FSTP anw
invoke printf,ADDR outfmt,anw
invoke ExitProcess,0
end start
 ;*】*/
  1. 统计对角线元素之和并输出。以下程序运行后,首先输入一个小于10的整数n,然后输入n行n列的整数矩阵,最后统计对角线元素(行列下标值相等或行列下标值之和等于n-1)之和并输出。
    运行后若输入:
    5
    9 8 6 4 2
    1 2 3 4 5
    6 7 8 9 3
    0 9 8 7 6
    5 4 3 2 1
    则结果输出:
    47
    请在;/和;/之间编写程序。

思路:二维数组对角线累加的坐标为x=y和x+y+1=n
所以在二维while循环中判断坐标,此题为ESI=EDI时和ESI+EDI+1=n时为对角线坐标(若坐标初始值为0时才需要加上1,若初始值为1就不需要)

.386				;选择的处理器
.model flat, stdcall		;存储模型,Win32程序只能用平展(flat)模型
option casemap:none		;指明标识符大小写敏感
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg	;C语言printf函数原型声明
.data				;⑤数据段
fmt  	BYTE	'%d',0
Sum    DWORD 0
n      DWORD ?
Arr    DWORD 10 DUP(10 DUP (?))
.code
start:
invoke scanf,addr fmt,addr n
MOV ESI,0
MOV EBX,0
.WHILE ESI<n
MOV EDI,0
.WHILE EDI<n
pushA      
invoke scanf,addr fmt,addr Arr[EBX+EDI*4]
popA     
INC EDI
.ENDW
INC ESI
MOV EAX,n
SHL EAX,2
LEA EBX,[EBX+EAX]
.ENDW
 ;*【*/
MOV ESI,0
MOV EBX,0
.WHILE ESI<n
MOV EDI,0
.WHILE EDI<n
MOV EAX,ESI
ADD EAX,EDI
ADD EAX,1
.IF ESI==EDI||EAX==n
MOV ECX,Sum
ADD ECX,Arr[EBX+EDI*4]
MOV Sum,ECX
.ENDIF
INC EDI
.ENDW
INC ESI
MOV EAX,n
SHL EAX,2    ;SHL    EAX,n为将数据左移,每移n位EAX都要更改为EAX*n*2,所以这里用上也就是EAX*4也就是n*4的意思
LEA EBX,[EBX+EAX]
.ENDW
 ;*】*/
invoke printf,addr fmt,Sum
ret
end start 
  1. 键盘输入若干个复数,分别求其模,最后再求所有模之和并显示(保留1位小数)。
    在这里插入图片描述
    运行后若输入:
    3.0 4.0
    1.0 1.0
    6.0 8.0
    则结果输出:
    16.4
    请在;/和;/之间编写程序。
.386
.model flat, stdcall
option casemap :none 
include kernel32.inc
includelib kernel32.lib
includelib	msvcrt.lib				;引用C库文件
printf PROTO C:ptr sbyte,:vararg	;C语言printf函数原型声明
scanf PROTO C:ptr sbyte,:vararg	;C语言scanf函数原型声明
 ;*【*/
.data
infmt BYTE '%lf',0
outfmt BYTE '%.1lf',13,10,0
x QWORD ?
tem QWORD ?
anw QWORD 0
mark DWORD 2
.code
start:
invoke scanf,ADDR infmt,ADDR x
MOV EDI,0
.WHILE EAX==1
INC EDI
MOV EAX,EDI
CDQ
IDIV mark
.IF EDX==0
FLD x
FMUL x
FADD tem
FSTP tem
FLD tem
FSQRT
FADD anw
FSTP anw
.ELSE
FLD x
FMUL x
FSTP tem
.ENDIF
invoke scanf,ADDR infmt,ADDR x
.ENDW
invoke printf,ADDR outfmt,anw
invoke ExitProcess,0
end start
 ;*】*/
  1. 键盘输入正整数n,编程求1到正整数n之间的所有奇数之和并输出。
    运行后若输入:5
    则结果输出:1到5的奇数和为9
    运行后若输入:10
    则结果输出:1到10的奇数和为25
    请在;/和;/之间编写程序。
.386
.model flat, stdcall
option casemap :none
include kernel32.inc
includelib kernel32.lib
includelib	msvcrt.lib		;引用C库文件
printf PROTO C:ptr sbyte,:vararg	;C语言printf函数原型声明
scanf PROTO C:ptr sbyte,:vararg	;C语言scanf函数原型声明
 ;*【*/
.data
input_fmt BYTE '%d',0
output_fmt BYTE '1到%d的奇数和为%d',13,10,0
n DWORD ?
anw DWORD 0
x DWORD 2
.code
start:
invoke scanf,ADDR input_fmt,ADDR n
MOV ECX,n
MOV EBX,anw
.WHILE ECX>0
MOV EAX,ECX
CDQ
IDIV x
.IF EDX!=0
ADD EBX,ECX
.ENDIF
dec ECX
.ENDW
MOV anw,EBX
invoke printf,ADDR output_fmt,n,anw
invoke ExitProcess,0
end start
 ;*】*/
  1. 编写求1+2+3+…+n和的程序(整数n由键盘输入且n>1)。
    运行后若输入:10
    则结果输出:1+…+10=55
    运行后若输入:100
    则结果输出:1+…+100=5050
    请在;/和;/之间编写程序。
    注意:不要删除或增加;/和;/;
 ;*【*/
.386
.model flat,stdcall
option casemap:none
include kernel32.inc
includelib kernel32.lib
includelib msvcrt.lib
scanf PROTO C:DWORD,:vararg
printf PROTO C:DWORD,:vararg
.data
input_fmt BYTE '%d',0
output_fmt BYTE '1+...+%d=%d',13,10,0
n DWORD ?
anw DWORD 0
.code
start:
invoke scanf,ADDR input_fmt,ADDR n
MOV ECX,n
MOV EAX,anw
.WHILE ECX>0
ADD EAX,ECX
dec ECX
.ENDW
MOV anw,EAX
invoke printf,ADDR output_fmt,n,anw
invoke ExitProcess,0
end start
 ;*】*/
  1. 键盘输入一串字符(最多80个字符),输出其中的数字。
    运行后若输入:ab4du5jkf8
    则结果输出:458
    请在;/和;/之间编写程序。

思路:要判断字符串中单个字符首先要求出整个字符串的长度才能遍历字符串取出单个字符判断(字符串长度计算代码于书本P204),判断完长度后,汇编可以和C语言一样将字符串当成字符数组操作(即字符串S可以和数组一样用S[n]取出第n个位置的字符),取出的字符通过ASCII码判断是否为数字(数字的码值为48~57),如果是数字直接输出即可(也可保存在数组中再做处理或输出)。

 ;*【*/
.386
.model flat,stdcall
option casemap:none
include kernel32.inc
includelib kernel32.lib
includelib msvcrt.lib
scanf PROTO C:DWORD,:vararg
printf PROTO C:DWORD,:vararg
.data
infmt BYTE '%s',0
outfmt BYTE '%c',0
s BYTE 80 DUP(?)
l DWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR s
MOV AL,0
LEA EDI,s-1
MOV ECX,80
.repeat
INC EDI
.untilcxz[EDI]==AL
LEA EAX,s
SUB EDI,EAX
MOV l,EDI
MOV EDI,0
.WHILE EDI<l
.IF s[EDI]>=48&&s[EDI]<=57
invoke printf,ADDR outfmt,s[EDI]
.ENDIF
INC EDI
.ENDW
invoke ExitProcess,0
end start
 ;*】*/
  1. 键盘输入若干对整数x、y,求其相应的最小公倍数。
    运行后若输入:
    18 12
    8 12
    10 12
    则结果输出:
    36
    24
    60
    请在;/和;/之间编写程序。

思路:最小公倍数=两整数的乘积÷最大公约数
所以,先用辗转相减法求出两数的最大公约数,然后将两数相乘除以最最大公约数即可得出最小公倍数

.386
.model flat, stdcall
include kernel32.inc
includelib kernel32.lib
includelib	msvcrt.lib				;引用C库文件
printf PROTO C:ptr sbyte,:vararg	;C语言printf函数原型声明
scanf PROTO C:ptr sbyte,:vararg	;C语言scanf函数原型声明
option casemap :none 
 ;*【*/
.data
infmt BYTE '%d%d',0
outfmt BYTE '%d',13,0
x DWORD ?
y DWORD ?
tem DWORD ?
anw DWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
MOV ESI,x
MOV EDI,y
.repeat
.IF ESI>EDI
MOV EBX,ESI
SUB EBX,EDI
MOV ESI,EBX
.ELSE
MOV EBX,EDI
SUB EBX,ESI
MOV EDI,EBX
.ENDIF
.until ESI==EDI
MOV tem,EBX
MOV EAX,x
IMUL EAX,y
CDQ
IDIV tem
MOV anw,EAX
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
invoke ExitProcess,0
end start
 ;*】*/
  1. 键盘输入若干对实数x、y,求各对实数乘积和。
    运行后若输入:
    2.5 2
    1.5 4
    2.2 2
    则结果输出:
    15.4
    请在;/和;/之间编写程序。
 ;*【*/
.386
.model flat, stdcall
option casemap :none 
include kernel32.inc
includelib kernel32.lib
includelib	msvcrt.lib				;引用C库文件
printf PROTO C:ptr sbyte,:vararg	;C语言printf函数原型声明
scanf PROTO C:ptr sbyte,:vararg	;C语言scanf函数原型声明
.data
infmt BYTE '%lf',0
outfmt BYTE '%.1lf',13,10,0
x QWORD ?
tem QWORD ?
anw QWORD 0
mark DWORD 2
.code
start:
invoke scanf,ADDR infmt,ADDR x
MOV EDI,0
.WHILE EAX==1
INC EDI
MOV EAX,EDI
CDQ
IDIV mark
.IF EDX==0
FLD x
FMUL tem
FSTP tem
FLD anw
FADD tem
FSTP anw
.ELSE
FLD x
FSTP tem
.ENDIF
invoke scanf,ADDR infmt,ADDR x
.ENDW
invoke printf,ADDR outfmt,anw
invoke ExitProcess,0
end start
 ;*】*/
  1. 键盘输入若干对整数x、y,求其相应的最大公约数。
    运行后若输入:
    18 12
    8 12
    10 12
    则结果输出:
    6
    4
    2
    请在;/和;/之间编写程序。

思路:最大公约数使用辗转相减法

例:辗转相减法

有两整数a和b:

① 若a>b,则a=a-b

② 若a<b,则b=b-a

③ 若a=b,则a(或b)即为两数的最大公约数

④ 若a≠b,则再回去执行①

例如求27和15的最大公约数过程为:

27-15=12( 15>12 )

15-12=3( 12>3 )

12-3=9( 9>3 )

9-3=6( 6>3 )

6-3=3( 3==3 )

因此,3即为最大公约数

//C语言代码:
#include<stdio.h>
void main ( )  /* 相减法求最大公约数 */
{  
   int m, n, a, b, c;
   printf("Input two integer numbers:\n");
   scanf ("%d,%d", &a, &b);m=a; n=b; 
     /* a, b不相等,大数减小数,直到相等为止。*/ 
   while ( a!=b) 
         if (a>b)  a=a-b;     
		 else  b=b-a;
   printf("The largest common divisor:%d\n", a);
   printf("The least common multiple:%d\n", m*n/a);
}
汇编代码

 ;*【*/
.386
.model flat,stdcall
option casemap:none
include kernel32.inc
includelib kernel32.lib
includelib msvcrt.lib
scanf PROTO C:DWORD,:vararg
printf PROTO C:DWORD,:vararg
.data
infmt BYTE '%d%d',0
outfmt BYTE '%d',13,0
x DWORD ?
y DWORD ?
anw DWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
MOV ESI,x
MOV EDI,y
.repeat
.IF ESI>EDI
MOV EBX,ESI
SUB EBX,EDI
MOV ESI,EBX
.ELSE
MOV EBX,EDI
SUB EBX,ESI
MOV EDI,EBX
.ENDIF
.until ESI==EDI
MOV anw,EBX
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
invoke ExitProcess,0
end start
 ;*】*/

after all

数组输入输出是下标更改的定义:

汇编中数组的定义为(DWORD 80 DUP(?) ‘80’为可以防止多少字节)所以汇编数组在输入输出时的下标根据数据类型的占用字节多少来更改的,比如一个字符数组中一个字符占用一个字节,所以输入输出时只用直接将数组下标累加(每次只加上1)就可以,但是DWORD数组中的每一个DWORD都占用四个字节,所以下标的更改就需要一次加上4,因为每个DWORD占用了四个字节,所以下一个DWORD就应该在上一个DWORD的四个字节后,当然也可以下标每次累加1然后乘上占用的字节数(如4)实现的效果是一样的。
二维数组输入输出下标更改的方法,以第三题为例,二维数组的每一排的头纵坐标都是数组的上一排的横坐标的累加值(也就是每行存放的n个数据乘上占用的字符数累加),横坐标则根据数据类型由零累加。而数组中每一个数据的下标则是头纵坐标加上横坐标,如第三题每个数据坐标就是(ESI *n *4+EDI *4:ESI由0开始累加到n,因为每行有n个数据,而且每个数据都占用4个字节,又有n行,所以每行的头纵坐标就是ESI *n *4,然后加上行中每个数据的下标EDI *4),也就是说到下一行时需要把上一行的所有坐标累加作为下一行的头纵坐标,如第三题的第一行的头纵坐标为ESI *n *4=0 *5 *4=0,第二行为ESI *n *4=1 *5 *4=20。但是汇编中没有办法执行直接的乘法累加所以就类似第三题的累加方法或者这样:

MOV EBX,0
MOV ESI,0
.WHILE ESI<n
MOV EDI,0
.WHILE EDI<n
Arr[EBX+EDI*4]
INC EDI
.ENDW
INC ESI
MOV EAX,n
LEA EBX,[EBX+EAX*4]
.ENDW
这里的意思是将EBX为0开始,0也就是第一行的头纵坐标,然后每取完一行数据就加上n*4(每行横坐标的累加值
作为下一行的头纵坐标)用累加的方式实现ESI*n*4。

也可以是:

MOV ESI,0
.WHILE ESI<n
MOV EBX,ESI
IMUL EBX,n
IMUL EBX,4
MOV EDI,0
.WHILE EDI<n
Arr[EBX+EDI*4]
INC EDI
.ENDW
INC ESI
.ENDW
这就是直接实现ESI*n*4

考题(IMPORTANT!)

输入一个字符和一个不含空格的字符串,统计该字符在字符串中出现的次数。
运行后输入:
s Thisisateststring
则结果输出:
'Thisisateststring’中有4个’s’字符
运行后输入:
h This
则结果输出:
'This’中有1个’h’字符

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
infmt BYTE '%c %s',0
outfmt BYTE '''%s''中有%d个''%c''字符',13,10,0
x BYTE ?
S BYTE 80 DUP(0)
anw DWORD 0
len DWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR S
MOV EDI,0
MOV ESI,0
MOV AL,x
.WHILE S[EDI]!=0
MOV AH,S[EDI]
.IF AH==AL
INC ESI
.ENDIF
INC EDI
.ENDW
MOV anw,ESI
invoke printf,ADDR outfmt,ADDR S,anw,DWORD PTR x
RET
end start

编程实现一简易加密算法,规则是:将每个小写字母循环后移4个位置,即a->e,b->f,c->g,…,v->z,w->a,x->b,y->c,z->d。
运行后输入明文:
abcdefghijklmnopqrstuvwxyz
则输出结果密文:
efghijklmnopqrstuvwxyzabcd

.386
.model flat, stdcall
include kernel32.inc
includelib kernel32.lib
includelib	msvcrt.lib				;引用C库文件
printf PROTO C:ptr sbyte,:vararg	;C语言printf函数原型声明
scanf PROTO C:ptr sbyte,:vararg	;C语言scanf函数原型声明
option casemap :none 
 ;*【*/
.data
infmt BYTE '%s',0
outfmt BYTE '%c',0
s BYTE 80 DUP(0)
len DWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR s
MOV EDI,0
MOV ESI,0
.WHILE s[EDI]!=0
.IF s[EDI]>='a'&&s[EDI]<='v'||s[EDI]>='A'&&s[EDI]<='V'
MOV EAX,DWORD PTR s[EDI]
ADD EAX,4
.ELSE 
MOV EAX,DWORD PTR s[EDI]
SUB EAX,22
.ENDIF
invoke printf,ADDR outfmt,EAX
INC EDI
.ENDW
RET
end start
 ;*】*/

编程求若干个长方体的体积,输入长宽高,输出体积,结果保留2位小数。
注意:不限定输入数据的个数
运行后若输入:
2.0 3.0 4.0
则结果输出:
24.00
运行后若输入:
1 2 3 2 3 4
则结果输出:
6.00 24.00

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%lf%lf%lf',0
outfmt BYTE '%.2lf ',0
x QWORD ?
y QWORD ?
z QWORD ?
anw QWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y,ADDR z
.WHILE EAX==3
FLD x
FMUL y
FMUL z
FSTP anw
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y,ADDR z
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干个圆柱的体积,输入底面半径和高,输出体积,π=3.14,结果保留2位小数。注意:不限定输入数据的个数
运行后若输入:
2.0 3.0
则结果输出:
37.68
运行后若输入:
1 2 3 4
则结果输出:
6.28 113.04

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%lf%lf',0
outfmt BYTE '%.2lf ',0
x QWORD ?
y QWORD ?
PI QWORD 3.14
anw QWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
FLD x
FMUL x
FMUL PI
FMUL y
FSTP anw
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干字符串的长度(字符串以0作为结束标志)。
运行后若输入:
abc
则结果输出:
3
运行后若输入:
abcdef abc
则结果输出:
6
3

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%s',0
outfmt BYTE '%d ',13,10,0
s BYTE 80 DUP(0)
.code
start:
invoke scanf,ADDR infmt,ADDR s
.WHILE EAX==1
MOV EDI,0
.WHILE s[EDI]!=0
INC EDI
.ENDW
invoke printf,ADDR outfmt,EDI
invoke scanf,ADDR infmt,ADDR s
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干个圆锥的体积,输入底面半径和高,输出体积,π=3.14,结果保留2位小数。注意:不限定输入数据的个数
运行后若输入:
2.0 3.0
则结果输出:
12.56
运行后若输入:
1 2 3 4
则结果输出:
2.09 37.68

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%lf%lf',0
outfmt BYTE '%.2lf ',0
x QWORD ?
y QWORD ?
PI QWORD 3.14
tag QWORD 3.0
anw QWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
FLD x
FMUL x
FMUL PI
FMUL y
FDIV tag
FSTP anw
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干个长方形的面积,输入长宽,输出面积,结果保留2位小数。
注意:不限定输入数据的个数。
运行后若输入:
2.0 3.0
则结果输出:
6.00
运行后若输入:
1 2 3 2 3 4
则结果输出:
2.00 6.00 12.00

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%lf%lf',0
outfmt BYTE '%.2lf ',0
x QWORD ?
y QWORD ?
anw QWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
FLD x
FMUL y
FSTP anw
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干个圆的面积,输入圆的半径,输出面积,π=3.14,结果保留2位小数。
注意:不限定输入数据的个数。
运行后若输入:
2.0
则结果输出:
12.56
运行后若输入:
1 2
则结果输出:
3.14 12.56

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%lf',0
outfmt BYTE '%.2lf ',0
x QWORD ?
PI QWORD 3.14
anw QWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x
.WHILE EAX==1
FLD x
FMUL x
FMUL PI
FSTP anw
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干个直角三角形的斜边,输入两直角边,输出斜边,结果保留2位小数。
注意:不限定输入数据的个数。
运行后若输入:
3.0 4.0
则结果输出:
5.00
运行后若输入:
3 4 6 8
则结果输出:
5.00 10.00

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%lf%lf',0
outfmt BYTE '%.2lf ',0
x QWORD ?
y QWORD ?
flag QWORD ?
anw QWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
FLD x
FMUL x
FSTP flag
FLD y
FMUL y
FADD flag
FSQRT
FSTP anw
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干个直角三角形的面积,输入两直角边,输出面积,结果保留2位小数。
注意:不限定输入数据的个数。
运行后若输入:
3.0 4.0
则结果输出:
6.00
运行后若输入:
3 4 6 8
则结果输出:
6.00 24.00

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%lf%lf',0
outfmt BYTE '%.2lf ',0
x QWORD ?
y QWORD ?
flag QWORD 2.0
anw QWORD ?
.code
start:
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
FLD x
FMUL y
FDIV flag
FSTP anw
invoke printf,ADDR outfmt,anw
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干对整数(x、y)的余数(x%y)之和,每输入一对整数x和y,就求一次它们的余数(x%y),然后将所有余数累加,最后输出累加和。
注意:输入数据成对输入,但不限定对数。
运行后若输入:
17 4
则结果输出:
1
运行后若输入:
17 4 8 5
则结果输出:
4

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%d%d',0
outfmt BYTE '%d ',13,10,0
x DWORD ?
y DWORD ?
anw DWORD 0
.code
start:
MOV ECX,0
invoke scanf,ADDR infmt,ADDR x,ADDR y
.WHILE EAX==2
MOV EAX,x
CDQ
IDIV y
MOV ECX,anw
ADD ECX,EDX
MOV anw,ECX
invoke scanf,ADDR infmt,ADDR x,ADDR y
.ENDW
invoke printf,ADDR outfmt,anw
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

键盘输入一串字符(最多80个字符),输出其中的大写字母。
运行后若输入:ab4dA5DkC8
则结果输出:ADC

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%s',0
outfmt BYTE '%c',0
s BYTE 80 DUP(0)
.code
start:
invoke scanf,ADDR infmt,ADDR s
MOV EDI,0
.WHILE s[EDI]!=0
.IF s[EDI]>='A'&&s[EDI]<='Z'
invoke printf,ADDR outfmt,s[EDI]
.ENDIF
INC EDI
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end star

键盘输入一串字符(最多80个字符),输出其中的小写字母。
运行后若输入:ab4dA5DkC8
则结果输出:abdk

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%s',0
outfmt BYTE '%c',0
s BYTE 80 DUP(0)
.code
start:
invoke scanf,ADDR infmt,ADDR s
MOV EDI,0
.WHILE s[EDI]!=0
.IF s[EDI]>='a'&&s[EDI]<='z'
invoke printf,ADDR outfmt,s[EDI]
.ENDIF
INC EDI
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end star

输入若干正整数,求能被5整除的所有整数和。
运行后若输入:12 10 13 25 41 15 63
则结果输出:能被5整除的整数和为:50

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%d',0
outfmt BYTE '能被5整除的整数和为:%d ',13,10,0
x DWORD ?
y DWORD 5
anw DWORD 0
.code
start:
invoke scanf,ADDR infmt,ADDR x
.WHILE EAX==1
MOV EAX,x
CDQ
IDIV y
.IF EDX==0
MOV ECX,anw
ADD ECX,x
MOV anw,ECX
.ENDIF
invoke scanf,ADDR infmt,ADDR x
.ENDW
invoke printf,ADDR outfmt,anw
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

输入若干正整数,求除7余2的所有整数和。
运行后若输入:12 16 13 25 41 15 65
则结果输出:除7余2的整数和为:81

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%d',0
outfmt BYTE '除7余2的整数和为:%d ',13,10,0
x DWORD ?
y DWORD 7
anw DWORD 0
.code
start:
invoke scanf,ADDR infmt,ADDR x
.WHILE EAX==1
MOV EAX,x
CDQ
IDIV y
.IF EDX==2
MOV ECX,anw
ADD ECX,x
MOV anw,ECX
.ENDIF
invoke scanf,ADDR infmt,ADDR x
.ENDW
invoke printf,ADDR outfmt,anw
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end start

编程求若干字符串中数字字符的个数(字符串以0作为结束标志)。
运行后若输入:
a2b3c
则结果输出:
2
运行后若输入:
a2b3c4d5e67f a44b5c
则结果输出:
6
3

.386				;选择的处理器
.model flat, stdcall	
option casemap:none		;指明标识符大小写敏感
include	kernel32.inc	;要引用的头文件
includelib	kernel32.lib	;要引用的库文件
includelib	msvcrt.lib	;引用C库文件
scanf PROTO C:DWORD,:vararg	;C语言scanf函数原型声明
printf PROTO C:DWORD,:vararg;C语言printf函数原型声明
.data				;⑤数据段
 ;*【*/
infmt BYTE '%s',0
outfmt BYTE '%d',13,10,0
s BYTE 80 DUP(0)
.code
start:
invoke scanf,ADDR infmt,ADDR s
.WHILE EAX==1
MOV EDI,0
MOV ESI,0
.WHILE s[EDI]!=0
.IF s[EDI]>='0'&&s[EDI]<='9'
INC ESI
.ENDIF
INC EDI
.ENDW
invoke printf,ADDR outfmt,ESI
invoke scanf,ADDR infmt,ADDR s
.ENDW
 ;*】*/
invoke	ExitProcess,0		;退出进程,返回值为0
end star

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值