汇编水仙花关于寄存器问题求大佬解答

题目如下:

编一函数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

感觉跟我同学的代码相差不大 就是找不出错误原因…
小白求解!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值