| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4771 人关注过本帖, 1 人收藏
标题:请教罗云彬汇编中的一段程序
只看楼主 加入收藏
Hallelujah
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2008-9-18
收藏(1)
 问题点数:0 回复次数:28 
请教罗云彬汇编中的一段程序
罗云彬win32汇编第7章Clock.asm,也就是第203页 程序段  _CalcX
_CalcX        proc    _dwDegree,_dwRadius
        local    @dwReturn

        fild    dwCenterX
        fild    _dwDegree
        fldpi
        fmul            ;角度*Pi
        fild    _dwPara180
        fdivp    st(1),st    ;角度*Pi/180
        fsin            ;Sin(角度*Pi/180)
        fild    _dwRadius
        fmul            ;半径*Sin(角度*Pi/180)
        fadd            ;X+半径*Sin(角度*Pi/180)
        fistp    @dwReturn
        mov    eax,@dwReturn
        ret

_CalcX        endp
用的是浮点指令,用到了浮点数据寄存器,FPU共有8个浮点数据寄存器,FPR0---FPR7相连并组成一个循环。fild是入栈指令,如果一个整数压入了浮点数据寄存器中就自动被转换成了浮点数,一st0至st7动态表示8个寄存器,并不一定是st0表示FPR0、st7表示FPR7,
现在看一下操作数的载入过程。当第一次载入时候,数据被存放在ST,以后每次操作,堆栈上升,开始被载入的操作数也随之上移,
直到ST(7)。比如:
load a : ST(0) = a; ST(1) = 0; ST(2) = 0.....
load b : ST(0) = b; ST(1) = a; ST(2) = 0.....
load c : ST(0) = c; ST(1) = b; ST(2) = a.....
而这段程序的入栈时
fild dwCenterX   ;st(0)=dwCenterX
fild _dwDegree   ;st(0)=_dwDegree,st(1)=dwCenterX
fldpi            ;st(0)=PI,st(1)=_dwDegree,st(2)=dwCenterX
fmul             ;st(0)=PI*_dwDegree,st(1)=_dwDegree,st(2)=dwCenterX;fmul指的是st(0)<-st(0)*st(1)
fild _dwPara180  ;st(0)=180,st(1)=PI*_dwDegree,st(2)=_dwDegree,st(3)=dwCenterX
fdivp st(1),st   ;st(1)=st(0)/st(1);也就是说 st(1)=180/(PI*_dwDegree),而不是书上说的 角度*PI/180,是不是哪里不对呢,请大家帮忙。
搜索更多相关主题的帖子: 罗云彬 汇编 
2008-09-18 17:20
Hallelujah
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2008-9-18
收藏
得分:0 
_dwPara180  dw   180;也就是说_dwPara180值为180。
fdivp st(i),st的意思是st(i)<-st(0)/st(i)然后执行一次出栈。
得出以上结论是根据看雪网站的汇编浮点指令集:
http://www.,不知是不是看雪网站写错了,请大家指证。

[[it] 本帖最后由 Hallelujah 于 2008-9-18 18:03 编辑 [/it]]
2008-09-18 17:22
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
LZ,你真够细心的,我也看了,觉得不得其解~~
2008-09-18 23:37
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
这种指令不常用,不怎么熟.编个小程序试试看先~~~
2008-09-18 23:40
Hallelujah
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2008-9-18
收藏
得分:0 
我在一本国外下载的汇编上看到浮点除的如下解释:
With two register operands, these instructions compute the following quotients:
fdiv st(0), st(i) ;st(0) := st(0)/st(i)
fdiv st(i), st(0) ;st(i) := st(i)/st(0)
fdivp st(i), st(0) ;st(i) := st(i)/st(0)
fdivr st(i), st(i) ;st(0) := st(0)/st(i)
fdivrp st(i), st(0) ;st(i) := st(0)/st(i)
The fdivp and fdivrp instructions also pop st(0) after performing the division operation. The
value for i in this two instructions is computed before popping st(0).
再看《The Art Of Assembly Language》第六章 Floating Point Arithmetic
这样写:
With no operands, the fdiv and fdivp instructions pop ST0 and ST1, compute ST1/ST0, and push the result back onto the stack. The fdivr and fdivrp instructions also pop ST0 and ST1 but compute ST0/ST1 before pushing the quotient onto the stack.

With two register operands, these instructions compute the following quotients:

     fdiv( sti, st0 );      // ST0 := ST0/STi
     fdiv( st0, sti );      // STi := STi/ST0
     fdivp( st0, sti );     // STi := STi/ST0 then pop ST0
     fdivr( st0, sti );     // ST0 := ST0/STi
     fdivrp( st0, sti );    // STi := ST0/STi then pop ST0

这两者明显是矛盾的,到底 fdivp st(i),st 表示 st(i)<-st(i)/st(0)还是
st(i)<-st(0)/st(i)?
这个问题有没有高手来回答一下。
2008-09-19 11:03
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
从程序的运行结果来看,明显应该是"fdivp st(i),st 表示 st(i)<-st(i)/st(0)"
我在Intel手册上没查到fdivp 这个指令,却查到fdivrp 这条指令,Intel是这样说的: FDIVRP ST(i), ST(0)
      Divide ST(0) by ST(i), store result in ST(i), and pop the register stack.
2008-09-19 12:08
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
我推测:被除数应该首先入栈,因为可能被除数要先参加其它的运算,或通过其它的运算得出;而除数要相对后入栈,再处理比较方便些.所以在"fdivp st(i),st "中,st 是后入栈的除数,而st(i)是先入栈的被除数,最终的表示就是 st(i)<-st(i)/st(0).
2008-09-19 12:16
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
期待高人一锤定音中... ...
2008-09-19 12:18
Hallelujah
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2008-9-18
收藏
得分:0 
回复 8# ONEPROBLEM 的帖子
解决了,编了一段程序:
            .386
            .model flat,stdcall
            option casemap:none

include        windows.inc
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib

            .const
szCaption    db    'This is caption.',0
szStart        db    'the final value %x',0
            .data
szBuffer    db    32 dup(?)
            .data?
szValue        dd    ?
vFirst        dd    ?
vSecond        dd    ?
vThird        dd    ?

            .code
start:
    mov    vFirst,1000
    mov    vSecond,100
    mov    vThird,10
    mov    szValue,0
    finit
    fild    vFirst
    fild    vSecond
    fild    vThird
    fdivp    st(1),st
    fistp    szValue
    invoke    wsprintf,addr szBuffer,addr szStart,szValue
    invoke    MessageBox,NULL,offset szBuffer,offset szCaption,MB_OK
    invoke    ExitProcess,NULL
end    start
是三个值逐个压栈。1000,100,10
最后出来应该是10
表示 fdiv st(i),st 表示的是 st(i)<-st(i)/st(0),看雪网站上写错了。

[[it] 本帖最后由 Hallelujah 于 2008-9-19 17:47 编辑 [/it]]
2008-09-19 17:45
Hallelujah
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2008-9-18
收藏
得分:0 
还有一个问题,怎样把硬盘上的图片上传到论坛上。
2008-09-19 17:49
快速回复:请教罗云彬汇编中的一段程序
数据加载中...
 
   



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

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