| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2548 人关注过本帖
标题:C中的汇编
只看楼主 加入收藏
prankmoon
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:161
专家分:921
注 册:2009-7-21
收藏
得分:0 
回复 10楼 wxjeacen

他是内联汇编,只需把最终结果放到eax,编译器不敢给你覆盖这个值的,而函数的结果一般正是用eax返回的;不是 x * y,楼主理解有误。

[ 本帖最后由 prankmoon 于 2009-8-17 18:59 编辑 ]
2009-08-17 18:55
wxjeacen
Rank: 7Rank: 7Rank: 7
等 级:禁止访问
帖 子:1291
专家分:628
注 册:2009-3-22
收藏
得分:0 
linux下的内联汇编。

如果没错,应该是这么实现你说的那个功能。

Please check.

test_c.tar.gz (11.48 KB)

生命不熄,战斗不止.
2009-08-17 19:36
wxjeacen
Rank: 7Rank: 7Rank: 7
等 级:禁止访问
帖 子:1291
专家分:628
注 册:2009-3-22
收藏
得分:0 
有没有windows下的操作结果测试下我的code.

生命不熄,战斗不止.
2009-08-17 19:37
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
序数型结果返回时,如果可能,都在CPU寄存器中。字节在AL中返回,字在AX中返回,双字在EAX中返回。
 
实数结果返回在数字协处理器的栈顶寄存器(ST(0))。对于Currency类型的函数结果,返回值被乘以10000倍。例如,Currency值1.234作为12340返回到ST(0)中。
 
Int64等类型的函数结果,一般实现为EDX:EAX这样的形式返回,但很多C编译器是将其实现为一个临时栈变量,效果相当于函数结果作为一个额外的var参数被声明在函数声明的参数之后。

所以如果你对你使用的编译器不是非常了解的话,这样的代码还是避免吧。

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2009-08-18 08:26
wxjeacen
Rank: 7Rank: 7Rank: 7
等 级:禁止访问
帖 子:1291
专家分:628
注 册:2009-3-22
收藏
得分:0 
我写的汇编说不定比你写的C都要多。

生命不熄,战斗不止.
2009-08-18 09:55
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
可笑

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2009-08-18 12:13
prankmoon
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:161
专家分:921
注 册:2009-7-21
收藏
得分:0 
楼主这段代码正好不需要处理栈帧即可很好的工作(因为没有分配函数的局部变量等与此类似的东西)。

能写这样代码的人应该是很好的理解了编译器是怎么处理内联汇编以及内联函数的。

我猜测这段代码是供VC用的,当然仅仅只是猜测而已。

我写了如下的测试代码,VC6,release方式:
#include <stdio.h>
#include <stdlib.h>

static __inline int MULSHIFT32(int x, int y)
{
    __asm {
        mov         eax, x
        imul        y
        mov         eax, edx
    }
}

int main(void)
{
    int a, b, c;
   
    scanf("%d %d", &a, &b);
    c = MULSHIFT32(a, b);

    printf("%d\n", c);
   
    return 0;
}
反汇编后:
00401000  /$  55            push    ebp                            ;  main
00401001  |.  8BEC          mov     ebp, esp
00401003  |.  83EC 08       sub     esp, 8
00401006  |.  8D45 F8       lea     eax, dword ptr [ebp-8]
00401009  |.  8D4D FC       lea     ecx, dword ptr [ebp-4]
0040100C  |.  50            push    eax
0040100D  |.  51            push    ecx
0040100E  |.  68 34804000   push    00408034                       ;  ASCII "%d %d"
00401013  |.  E8 59000000   call    <scanf>
00401018  |.  8B45 FC       mov     eax, dword ptr [ebp-4]         ;  //内联函数 MULSHIFT32;[ebp-4]为a(注意,并不存在普通函数的值拷贝的问题)
0040101B  |.  F76D F8       imul    dword ptr [ebp-8]              ;  [ebp-8]为b
0040101E  |.  8BC2          mov     eax, edx                       ;  \\
00401020  |.  50            push    eax                            ;  内联函数的结果,因为编译器优化的原因,所以找不到变量c了,也因此,地址401003处esp减去的是8(a和b各占4字节),而不是0x0C
00401021  |.  68 30804000   push    00408030                       ;  ASCII "%d",LF
00401026  |.  E8 15000000   call    <printf>
0040102B  |.  83C4 14       add     esp, 14
0040102E  |.  33C0          xor     eax, eax
00401030  |.  8BE5          mov     esp, ebp
00401032  |.  5D            pop     ebp
00401033  \.  C3            retn

这个帖子中有一段关于inline函数的说明,很中肯:
  ---- http://bbs.

[ 本帖最后由 prankmoon 于 2009-8-18 13:00 编辑 ]
2009-08-18 12:24
wxjeacen
Rank: 7Rank: 7Rank: 7
等 级:禁止访问
帖 子:1291
专家分:628
注 册:2009-3-22
收藏
得分:0 
这种问题有点小儿科。

我到win下check了下,你那段code的功能我的跟我的一样

我奇怪的是win下的edx 开始不清零,内联有入口,没出口也能跑,真shit.

最近发现,IBM的服务器下的汇编貌似跟intel 或者at&t 都不一样。

貌似挺好玩的。



生命不熄,战斗不止.
2009-08-18 15:23
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:3 
= =wx大牛啊,你怎么就写了那么多行呢?

刚查了AMD的文档:
The MUL instruction's mnemonic has only one operand, which is a factor. The multiplicand operand is
always assumed to be an accumulator register. For byte-sized multiplies, AL contains the multiplicand,
and the result is stored in AX. For word-sized, doubleword-sized, and quadword-sized multiplies, rAX
contains the multiplicand, and the result is stored in rDX and rAX.


所以,应该是自动清零的……

附我的代码:
程序代码:
static inline int IMULSHL32(int lhs, int rhs)
{
    int res;
    asm("imull %2" : "=d"(res) : "a"(lhs), "m"(rhs));
    return res;
}



专心编程………
飞燕算法初级群:3996098
我的Blog
2009-08-19 09:01
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
哦,上面的资料是mul的,不过AMD的手册说,imul的单参数版本是和mul是一样的。

那个,wx大牛既然汇编写的比别人的C代码还多,那贴个自己写的汇编非递归快排如何?

专心编程………
飞燕算法初级群:3996098
我的Blog
2009-08-19 09:04
快速回复:C中的汇编
数据加载中...
 
   



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

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