题目如下:
编一函数fun(int num)用于判断整数num是否是水仙花数。所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身,如153=13+53+33。
运行后输入:
153
则结果输出:
是水仙花数
运行后输入:
123
则结果输出:
不是水仙花数
请在;【/和;】/之间编写程序。
/源程序asm/
.386 ;选择的处理器
.model flat, stdcall ;存储模型,Win32程序只能用平展(flat)模型
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 ;⑤数据段
fmt BYTE ‘%d’,0 ;定义变量
fmt2 BYTE ‘%s’,0 ;定义变量
number DWORD 0
s1 BYTE ‘是水仙花数’,0
s2 BYTE ‘不是水仙花数’,0
.code ;⑥代码段
;【/
;】/
start: ;定义标号start
invoke scanf,ADDR fmt,ADDR number ;输入number的值
invoke fun,number
invoke ExitProcess,0 ;退出进程,返回值为0
end start ;指明程序入口点start
本人在此之前已经完成
代码如下:
fun proc n:dword
local x:dword,y:dword
mov esi,n ;153
mov x,10
mov ecx,0
.while esi!=0
mov eax,esi
cdq
mov esi,eax ;15 1
mov y,edx ;3 5 1
mov eax,y
mul y
mul y
add ecx,eax
.endw
.if ecx==n ;是水仙花数
invoke printf ,addr s1
.else
invoke printf ,addr s2
.endif
ret
fun endp
于是同学问我 为什么他的代码不对…
代码如下:
fun proc x:dword
mov ebx,0
mov ecx,10
mov eax,x
.while eax!=0
cdq
div ecx
mov edi,eax
mov eax,edx
mul edx
mul edx
add ebx,eax
mov eax,edi
.endw
.if ebx == x
invoke printf,addr fmt2,addr s1
.else
invoke printf,addr fmt2,addr s2
.endif
ret
fun endp
我找的错误是寄存器转移时内容转移时出现问题。
下面是我发现问题后的几个疑问。
希望有大佬帮忙解答:
1.为什么单纯输出一个寄存器时内容正常而两个寄存器内容都输出时edx的值好像变成了地址?
如下图:
2.后续的输出eax值中在第一个mul edx 还能输出值来,后面的输出又变成地址了???
终究还是实力不够。
invoke printf,addr fmt,eax
至于寄存器错误原理不懂得如何解决。但是在同学代码的基础上加了两个定义的 p,q 来储存 除数和余数是可以成功的解决问题的。
代码如下:
fun proc x:dword
local p:dword ,q:dword
mov ebx,0
mov ecx,10
mov eax,x
.while eax != 0
cdq
div ecx
mov p,eax
mov q,edx
mov eax,q
mul q
mul q
add ebx,eax
mov eax,p
.endw
.if ebx == x
invoke printf,addr fmt2,addr s1
.else
invoke printf,addr fmt2,addr s2
.endif
ret
fun endp
查看其它大佬解题代码:
.386 ;选择的处理器
.model flat, stdcall ;存储模型,Win32程序只能用平展(flat)模型
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 ;⑤数据段
fmt BYTE '%d',0 ;定义变量
fmt2 BYTE '%s',0 ;定义变量
n DWORD 0
s1 BYTE '是水仙花数',0
s2 BYTE '不是水仙花数',0
.code ;⑥代码段
;*【*/
fun PROC x:DWORD
MOV EBX,0
MOV ECX,10
MOV EAX,x
.WHILE EAX!=0
CDQ
IDIV ECX
MOV EDI,EAX
MOV EAX,EDX
IMUL EAX,EDX
IMUL EAX,EDX
ADD EBX,EAX
MOV EAX,EDI
.ENDW
.IF EBX==x
invoke printf,ADDR fmt2,ADDR s1
.ELSE
invoke printf,ADDR fmt2,ADDR s2
.ENDIF
RET
fun ENDP
;*】*/
start: ;定义标号start
invoke scanf,ADDR fmt,ADDR n ;输入n的值
invoke fun,n
invoke ExitProcess,0 ;退出进程,返回值为0
end start ;指明程序入口点start
感觉跟我同学的代码相差不大 就是找不出错误原因…
小白求解!