受不了了。。。汇编汇编,帮忙看下这个程序

antion692980794 2011-06-01 03:26:44

.程序通过调用函数求出数组的最大值,最小值,平均值
.386
.MODEL FLAT

ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

include io.h ; header file for input/output

cr equ 0dh ; carriage return character
Lf equ 0ah ; line feed
maxlen equ 100 ;数组最大长度

.STACK 4096 ; reserve 4096-byte stack

.DATA ; reserve storage for data

prompt1 BYTE 'Now Init the Array ',cr,Lf,Lf,0
prompt2 BYTE 'please input a number :',0
prompt3 BYTE 'please input the length of Array :',0
MaxNum BYTE cr,Lf,'the max number is : ',0
MinNum BYTE cr,Lf, 'the min number is : ',0
Ave BYTE cr,Lf,'the average number is : ',0

number BYTE 16 DUP (?)

Array DWORD maxlen DUP(?)
Result DWORD 3 DUP(?)
Len DWORD ?
Sum DWORD ?

Value BYTE 11 DUP(?) ,0



.CODE
; start of main program code

MaxMinAvg PROC NEAR32 ;结果存放在Result中
push ebp ; establish stack frame
mov ebp,esp
pushad
pushf ; save flags


mov ebx,[ebp+16] ;数组首地址
mov ecx,[ebp+12] ;数组长度
mov edx,[ebp+8] ;结果数组地址

mov eax,[ebx] ;累加和
mov [edx],eax ;初始化数据
mov [edx+4],eax
mov [edx+8],eax

forcount:
mov eax,[ebx]
cmp eax,[edx]
jg Big;
cmp eax,[edx+4]
jb Small
jmp Com
Small :
mov [edx+4],eax
jmp Com
Big :
mov [edx],eax
jmp Com
Com :
add eax,Sum
mov Sum,eax
add ebx,4
loop forcount
endfor :
mov eax,Sum
mov ecx,[ebp+12] ;数组长度
idiv ecx
mov [edx+8],eax ;平均数
popf
popad
pop ebp
ret
MaxMinAvg ENDP


_start:
output prompt1
Safe: output prompt3
input number,16
atod number
cmp eax,maxlen
jg Safe ; 超过范围再次输入
mov len,eax ;输入数组长度
lea ebx,Array ;取数组首地址

mov ecx,len
forArray:
output prompt2
input number,16
atod number
mov [ebx],eax
add ebx,4
loop forArray ;循环

lea ebx,Array ;取数组首地址
push ebx ;压入数组首地址
mov ecx,len
push ecx ;压入数组长度
lea edx,Result
push edx ;压入结果数组
call MaxMinAvg
add esp,12

;输出结果
output MaxNum
dtoa Value,[edx]
output Value

output MinNum
dtoa Value,[edx+4]
output Value

output Ave
dtoa Value,[edx+8]
output Value

INVOKE ExitProcess, 0 ; exit with return code 0
PUBLIC _start ; make entry point public
END ; end of source code



调试得我快疯了。。。用ml命令和link命令。。。
总是出现莫名其妙的错误,比如说,我把大多数代码(函数部分都注释起来了),没错了,可以运行了,但是把函数的注释有条件的去掉(想通过这样来找出错误的地方),又出错了
比如这里
mov ebx,[ebp+16] ;数组首地址
mov ecx,[ebp+12] ;数组长度
mov edx,[ebp+8] ;结果数组地址

原来还好好的,这三句的注释去掉之后程序编译连接没问题,运行时就出错。。。
用windbg根本进不去,不像C/C++那样可以跟踪。。。哎。。。
实在不行了,不得不求助大家。
...全文
241 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
CppCoder 2011-06-02
  • 打赏
  • 举报
回复
用C等高级语言实现模块功能,
反汇编,
和自己写的比较,找不同
编译、调试运行自己写的
leebeen34 2011-06-02
  • 打赏
  • 举报
回复
没有好好学汇编,看不懂,学习一下
Meteor_Code 2011-06-02
  • 打赏
  • 举报
回复
看来是我记错了,刚才试了一下,a果然入栈后,esp指向这个a
Meteor_Code 2011-06-02
  • 打赏
  • 举报
回复
mov ebx,[ebp+16] ;数组首地址
mov ecx,[ebp+12] ;数组长度
mov edx,[ebp+8] ;结果数组地址
你进入函数后push了ebp,然后mov ebp,esp,这时候ebp指向栈顶,
ebp+4是你刚才push的ebp
ebp+8是你call的时候保存的返回指针
ebp+12才是你的第一个函数参数
lz应该仔细看看入栈和出栈
push后,esp指向的是一个新的机器字宽度,而不是你刚才push的那个机器字宽度的数据
ffjj56 2011-06-02
  • 打赏
  • 举报
回复
那个版块以前挺热闹啊
赵4老师 2011-06-02
  • 打赏
  • 举报
回复
单步调试和设断点调试是程序员必须掌握的技能之一。
ww2000e 2011-06-02
  • 打赏
  • 举报
回复
我安的masm没io.h...
xiaohuh421 2011-06-02
  • 打赏
  • 举报
回复
楼主,用OD动态调试吧
bluesky12312388 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 antion692980794 的回复:]

引用 22 楼 bluesky12312388 的回复:
汇编里面调用过程的时候是没有像C语言里面参数压栈这一说法,直接取就好了,
如果要进行保存的话在前面mov到其它寄存器。
而且取参数的时候是pop,最好不要用 mov ebx,[ebp+16]这种形式。

一般参数传递有:
1.用变量传递参数
2. 用寄存器传递参数
3. 用地址表传递参数
4. 用堆栈传递参数

你用……
[/Quote]
MaxMinAvg PROC NEAR32,
也有可能就是你这个NEAR32导致的,可能只有2bytes的偏移。
antion692980794 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 bluesky12312388 的回复:]
汇编里面调用过程的时候是没有像C语言里面参数压栈这一说法,直接取就好了,
如果要进行保存的话在前面mov到其它寄存器。
而且取参数的时候是pop,最好不要用 mov ebx,[ebp+16]这种形式。

一般参数传递有:
1.用变量传递参数
2. 用寄存器传递参数
3. 用地址表传递参数
4. 用堆栈传递参数

你用的就是第四种,最好是把通过pop的方式去访问参数……
[/Quote]
我们教材就是说要这样传递的。。。
这样保护了寄存器
不用堆栈的话直接用寄存器我觉得函数调用也没什么意义了的
--------------------------
哪位好心人帮忙改下吧
实在不行就结贴了 实在无满意答案
bluesky12312388 2011-06-02
  • 打赏
  • 举报
回复
汇编里面调用过程的时候是没有像C语言里面参数压栈这一说法,直接取就好了,
如果要进行保存的话在前面mov到其它寄存器。
而且取参数的时候是pop,最好不要用 mov ebx,[ebp+16]这种形式。

一般参数传递有:
1.用变量传递参数
2. 用寄存器传递参数
3. 用地址表传递参数
4. 用堆栈传递参数

你用的就是第四种,最好是把通过pop的方式去访问参数。
antion692980794 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 meteor_code 的回复:]
看来是我记错了,刚才试了一下,a果然入栈后,esp指向这个a
[/Quote]
esp四个字节 函数返回值4个字节
antion692980794 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hpf976149 的回复:]
用C等高级语言实现模块功能,
反汇编,
和自己写的比较,找不同
编译、调试运行自己写的
[/Quote]
额,看了也只能这样试试了
antion692980794 2011-06-02
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zhao4zhong1 的回复:]
单步调试和设断点调试是程序员必须掌握的技能之一。
[/Quote]
我知道 但是用windbg调试根本进不去 程序一开始就被强制退出 无奈
我也是没办法才发帖求助的
antion692980794 2011-06-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xx121355 的回复:]
你这是MASN吧?自动生成堆栈框架
应该把push ebp ; establish stack frame
mov ebp,esp
去掉试试
[/Quote]
说了不是这个的问题了
函数里面我就单独做压栈出栈 其他的注释掉 没问题
xx121355 2011-06-01
  • 打赏
  • 举报
回复
还有后面的POP ebp
xx121355 2011-06-01
  • 打赏
  • 举报
回复
你这是MASN吧?自动生成堆栈框架
应该把push ebp ; establish stack frame
mov ebp,esp
去掉试试
antion692980794 2011-06-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xx121355 的回复:]
MaxMinAvg PROC NEAR32 ;结果存放在Result中
push ebp ; establish stack frame
mov ebp,esp
pushad
pushf ; save flags


mov ebx,[ebp+16] ;数组首地址
mov ecx,[ebp+12] ;数组长度
mov edx,[ebp+8]……
[/Quote]
不是吧,压入之后不弹出么?再说那里绝对没问题的
原来我在实验室的时候弄好了,然后忘记拷回来了,重新写的时候又出错了。悲剧
antion692980794 2011-06-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 kid_coder 的回复:]
...LZ应该转去汇编板块
[/Quote]
那个板块太冷清了。。。
antion692980794 2011-06-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ww2000e 的回复:]
io.h用的什么?
[/Quote]
就用masm自带的
加载更多回复(5)

33,317

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧