| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 782 人关注过本帖
标题:汇编新手求教个问题
只看楼主 加入收藏
风动旗动
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2012-6-7
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:8 
汇编新手求教个问题
计算有符号数平均数
.data
array dword 675,354,-34,198
.code
start:
push lengthof array
push offset array
call mean
add esp,8
call dispsid
mean  proc
push ebp
mov ebp,esp
push ebx
push ecx
push edx
mov ebx,[ebp+8]
mov ecx,[ebp+12]
xor eax,eax
xor edx,edx
mean1: add eax,[ebx+edx*4]
add edx,1
cmp edx,ecx
jb mean1
cdq
idiv ecx
pop edx
pop ecx
pop ebx
pop ebp
ret
mean endp
这个程序为什么要用堆栈操作
还有cdq是什么指令
求高手不吝赐教
搜索更多相关主题的帖子: 计算 平均数 
2012-06-07 14:48
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:20 
指令你自己百度或查书

为啥用堆栈呢 保护寄存器的值 如果不保护 函数返回了对调用者会产生影响 要知道寄存器就这么几个
2012-06-07 14:58
风动旗动
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2012-6-7
收藏
得分:0 
谢谢哦
但我还是有点不懂。我们不是每次写程序都要重新对寄存器赋值,那为什么还要保护寄存器?而且这个程序不用堆栈直接用mov ecx,lengthof array
mov ebx,offset array也可以写啊,影响在哪呢?
2012-06-07 15:11
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
1 子程序开头和结尾成对出现的push和pop一般用于寄存器的保护

2 寄存器保护是函数或者子程序必须做的 当然有些时候可能没用 但这种做法是对的

3 win系统的习惯是 由子程序保护ebp esi edi ebx 其余不保护 保护的 调用前后寄存器的值不变 不保护的 可能变可能不变

4 记得要结题 不明白欢迎继续问
2012-06-07 15:15
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
你这里 当然可以用寄存器传值 不过人家程序没那么写呀

不要较真 书上的程序或者说是例子程序 只是展示功能 可能没啥实用性 甚至多此一举脱裤子放屁都可能 这就是例子程序而已
2012-06-07 15:17
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
.data
    array dword 675,354,-34,198
.code

start:
    push lengthof array
    push offset array
    call mean
    add esp,8
    call dispsid

mean  proc
    push ebp
    mov ebp,esp
    push ebx
    push ecx
    push edx
    mov ebx,[ebp+8]
    mov ecx,[ebp+12]
    xor eax,eax
    xor edx,edx
mean1: add eax,[ebx+edx*4]
    add edx,1
    cmp edx,ecx
    jb mean1
    cdq
    idiv ecx
    pop edx
    pop ecx
    pop ebx
    pop ebp
    ret
mean endp

补充一点 合理的缩进对于提高程序的可读性有很大的帮助 越是初学越要注意
2012-06-07 15:20
风动旗动
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2012-6-7
收藏
得分:0 
我明白了。果然光看书是不够的啊。
还有就是这个cdq指令--eax最高为1,edx=ffffffffh;为0则edx=0.看起来无关紧要,但我试了下没有这条指令就会有溢出错误是什么情况?
2012-06-07 15:38
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
指令的格式:CDQ         ;80386+
该指令的隐含操作数为EDX和EAX,指令的功能是用EAX的符号位填充EDX。指令的执行不影响任何标志位。

这个指令的功能是扩展符号位 帖一段书上的话罢

在作有符号除法时,有时需要把短位数的被除数转换成位数更长的数据类型。比如,要用BL中的数据去除AL,但根据除法指令的规定:除数是8位,则被除数必须是AX,于是就涉及到AH的取值问题。

为了方便说明,假设:(AH)=1H,(AL)=90H=-112D,(BL)=10H。

1)、在作除法运算前,必须处理AH的原有内容

假设在作除法时,不管AH中的值,这时,(AH、AL)/BL的商是19H,但我们知道:AL/BL的商应是-7,这就导致:计算结果不是所预期的结果,所以,在作除法运算前,程序员必须要处理AH中的值。

2)、作无符号数除法时

可强置AH的值为0,于是,可得到正确的结果。

3)、作有符号数除法时

如果强置AH为0,则AX=0090H,这时,AX/BL的商为9,显然结果也不正确。

如果把AL的符号位1,扩展到AH中,得:AX=0FF90H=-112D,这时,AX/BL的商就是我们所要的正确结果。

综上所述,因为在进行有符号数除法时存在隐含操作数数据类型转换的问题,所以,系统提供了四条数据类型转换指令:CBW、CWD、CWDE和CDQ。

这里如果不扩展 也就是不清0 会溢出 因为作为除数高位的edx是4 除以4肯定会溢出

怎么能是无关紧要呢 看书不思考 跟没看一样、、
2012-06-07 16:42
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
书上的东西 不贴出来 就不看 可惜啊 不是所有人都乐意帖出来
2012-06-07 16:43
快速回复:汇编新手求教个问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017433 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved