天下

记录修行的印记

C++整数、浮点数、结构体的返回值

 

#include "stdafx.h"


struct person{
    
int age;
    
int sex;
    
char name[20];
};

struct person GetPerson(int age,int sex,char* name)
{
    
struct person p;
    p.age 
= age;
    p.sex 
= sex;
    strcpy(p.name,name);
    
return p;
}

int main()
{
    
int m = 0x7ffff123;
    
int n = 0x7ffff456;
    
int k = 0x7fffffff;

    
//汇编指令:imul,mul
    long long x = (long long)(m * n);    //返回值类型为 int,然后强制转换为long long,最后赋值给x,
    long long y = (long long)m * n;        //返回值类型为 long long,然后赋值给y,注意强制类型转换括号的位置,
    

    
long long z = m * n;                //返回值类型为 int,然后赋值给x.
/*

汇编指令:
    004114BC  mov         eax,dword ptr [m] 
    004114BF  imul        eax,dword ptr [n] 
    004114C3  cdq          //数据扩展指令,将双字数据扩展为四字类型
    //CDQ—Convert Double to Quad (386+),该指令把edx扩展为eax的高位,也就是说变为64位。     
    004114C4  mov         dword ptr [z],eax 
    004114C7  mov         dword ptr [ebp-4Ch],edx 
*/

    printf(
"m = %d,n = %d \n",m,n);
    printf(
"x = %lld\n",x);
    printf(
"y = %lld\n",y);
    printf(
"z = %lld\n",z);





    
int m1 = 8;
    
int n1 = 3;
    
int k1 = m1/n1;

    
double k2 = m1/n1;        //返回值类型为 int,然后赋值给k2,汇编指令:idiv
/*

汇编指令:
    0041155E  mov         eax,dword ptr [m1] 
    00411561  cdq              
    00411562  idiv        eax,dword ptr [n1] 
    00411565  mov         dword ptr [ebp-1F4h],eax 
    0041156B  fild        dword ptr [ebp-1F4h] 
    00411571  fstp        qword ptr [k2] 

    fild和fstp都是x87指令 
    fild浮点加载整数 然后转换为长双精度  
    fild是将整数转化为长双精FP80压栈(压到st0),
    fstp是将弹栈指令,将st0弹出。

*/


    
double k3 = (double)(m1/n1);    //返回值类型为 int,然后强制转换为double,最后赋值给k3,汇编指令:idiv


    
double k4 = (double)m1/n1;        //返回值类型为double,然后赋值给k4,注意强制类型转换括号的位置,汇编指令:fidiv
/*

    汇编指令:
    00411590  fild        dword ptr [m1] 
    00411593  fidiv       dword ptr [n1] 
    00411596  fstp        qword ptr [k4] 
*/

    printf(
"k1=%d \r\n",k1);
    printf(
"k2=%f \r\n",k2);
    printf(
"k3=%f \r\n",k3);
    printf(
"k4=%f \r\n",k4);

    
char l1 = 127;
    
char l2 = 122;
    
int  l3 = l1* l2;
/*
汇编指令:
    0041162E  movsx       eax,byte ptr [l1] 
    00411635  movsx       ecx,byte ptr [l2] 
    0041163C  imul        eax,ecx 
    0041163F  mov         dword ptr [l3],eax 
*/



    
char l4 = l1* l2;
/*
    汇编指令:
    00411645  movsx       eax,byte ptr [l1] 
    0041164C  movsx       ecx,byte ptr [l2] 
    00411653  imul        eax,ecx 
    00411656  mov         byte ptr [l4],al 
*/




    
int l5 = l1/l2;
    
int l6 = double(l1)/l2;


    
long double k5 = l1* l2;
/*
    汇编指令:
    004116A6  movsx       eax,byte ptr [l1] 
    004116AD  movsx       ecx,byte ptr [l2] 
    004116B4  imul        eax,ecx 
    004116B7  mov         dword ptr [ebp-1F4h],eax 
    004116BD  fild        dword ptr [ebp-1F4h] 
    004116C3  fstp        qword ptr [k5] 
*/


    printf(
"l3=%d \r\n",l3);
    printf(
"l4=%d \r\n",l4);
    printf(
"k4=%lf \r\n",k5);

    
long long o1 = 0xff34567812345677;    
    
long long o2 = 0xab34567834125615;
    
long long o3 = o1 * o2;    //溢出

    
int age = 5;
    
int sex = 1;
    
char name[20= "Aaron";

    
struct person p1 = {5,1,"Aaron"};
    
struct person p2;
    
struct person* pp1 = &p1;
    
struct person* pp2 = &p2;
    p2
= p1;
/*
汇编指令:
00414348  mov         ecx,7 
0041434D  lea         esi,[ebp-188h] 
00414353  lea         edi,[ebp-1ACh] 
00414359  rep movs    dword ptr es:[edi],dword ptr [esi] 

//ecx 是计数器(counter),是重复(REP)前缀指令和LOOP指令的内定计数器。
因为sizeof(person) = 28,所以才有mov ecx,7 
*/


    
struct person p3;
    p3
= GetPerson(age,sex,name);


//结论:
/*

整数类型:
    小于等于4字节的返回值放在eax中,
    8字节的返回值放在edx + eax中,其中edx为高位,eax为低位.

浮点数类型:
计算是通过压栈的方式,如汇编指令:fild
返回是通过出栈的方式,如汇编指令:fstp

结构体类型赋值:
是通过内存拷贝的方式,如汇编指令:rep movs
将源值的地址放入esi,
将目标值的地址放入edi,

00414393  lea         esi,[ebp-2D8h] 
00414399  lea         edi,[ebp-1D0h] 
0041439F  rep movs    dword ptr es:[edi],dword ptr [esi] 


结构体类型返回值:
通过eax将结构体的指针返回
*/

    system(
"pause");
    
return 0;
}
//111111111111111111111111111111
//00000000000000000000000000000001
//
//111111111111111111001010111100
//10000000101011010101110111000010
//取反加一 1111111010100101010001000111110
//11111001111111111111111111111110000011000

//11111111111111111111110000011000
//1111101000


//11111010000000000000000000000000000000000 = 0
//00000000000000000000000000000000
//
//1111111111111111111110000011000

 

posted on 2013-03-01 10:16 天下 阅读(853) 评论(0)  编辑 收藏 引用 所属分类: C/C++汇编语言


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿(4)

随笔分类(377)

随笔档案(327)

链接

最新随笔

搜索

最新评论