• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

谈谈我对C51语言的看法

目前单片机的编程中,C51语言可以说是十分盛行,这种语言我也用过,但基本上都是用汇编语言.
C51语言的好处是可读性强、移植性好、浮点运算,除此之外没有别的好处了.我们不妨将两种语言作一个比较:
1、效率方面:我曾对编译后的C51语言分析过,可以发现由它生成的代码数量,至少是汇编语言的两倍以上,有的甚至高达十倍以上.占用空间大了,效率自然低.
2、移植性:C51的可移植性是比汇编好一些,但是单片机程序不同于微机控件程序那样通用,几乎没有一个程序是可以到处移植的.单片机中最常用的移植程序大概就是运算子程序了,在这方面,汇编格式的运算子程序移植起来一个也不比C51逊色.
3、浮点运算:以我的感觉,单片机不适合采用浮点运算,我曾经做过试验,编译了一个1.2+2.3的浮点运算,编译后代码长达2K多,完成这个运算所需要的时间就不用说了.我从八四年就开始研究单片机,到现在做过的系统中,含有单片机的超过五十项,所有系统中的运算,全部都采用定点运算,几个定点子程序成了法宝,代码效率非常高,请看下面的一段:

;W = W130 * (130 / Dia) * (130 / Dia) = W130 * 16900 / (Dia * Dia)
CalAndMem:      MOV     R5, SetPie130War1H
                MOV     R4, SetPie130War1L
                MOV     R3, #HIGH 16900
                MOV     R2, #LOW 16900
                CALL    QKMUL                           ;W130 * 16900
;双字节乘法子程QKMUL
;(R3、R2)*(R5、R4)=R7、R6、R5、R4
;R3、R5、R7为高字节
                MOV     A, SetDiamt
                MOV     B, A
                MUL     AB
                MOV     R3, B
                MOV     R2, A
                CALL    NDIV                            ; /(Dia * Dia)
;二进制除法子程:NDIV
;入口:R7654=被除数,R7高字节,R32=除数,R3高字节
;出口:R76=余数,R7高字节,R54=商,R5高字节
;R765432用于参数传递,不用保护
                MOV     SetPieWar1H, R5                 ;当前缸径下的压力报警点
                MOV     SetPieWar1L, R4

--------
其中的子程序都是网上的成品,非常精简.

4、实时性:用汇编编程序的人都知道,单片机的实时性要求很高,经常需要计算这段程序需要多长时间,什么时间来中断,中断后执行多长时间,对原程序有没有妨碍,等等,这都是C51程序难以做到的.
5、节省内存:当然,这和代码效率是成反比的,同样的内存所能完成的功能也就大大提高.
永远记住:高性能的代码是用汇编语言编写出来的,而不是用高级语言生成的,高质量的PCB是有经验的工程技术人员用手工排出来的,而不是软件自动布线出来的.
全部回复(21)
正序查看
倒序查看
hmf2006
LV.2
2
2006-01-09 22:25
顶一下!
我正在学习中!
汇编中的乘啊除啊定点浮点的还搞不明白!
请问有书推荐吗?
0
回复
maychang
LV.6
3
2006-01-11 01:32
完全同意楼主看法
再补充一句:最高精度的块规,是手工磨出来的.
0
回复
hxzlz
LV.3
4
2006-01-24 11:06
高手是这样练成的!
0
回复
hotpower
LV.5
5
2006-02-01 10:14
还是C语言快捷,想快就嵌入汇编.

http://blog.21ic.org/blog.asp?name=hotpower
0
回复
hotpower
LV.5
6
2006-02-03 03:28
再这样用汇编肯定要被时代淘汰...

现在是大容量高速度的年代.
0
回复
deyun
LV.4
7
2006-03-21 18:28
使用C51可以写出跟asm51毫不逊色的程序,这要看编程者的水平了,看下面的例子:
// ============================================================
// 功能:计算斜率
// 说明:被除数必须小于除数,返回(n1*256)/n2的商
// 编程:臧德运
unsigned char Div(unsigned char n1, unsigned char n2)
{
union {unsigned int w; struct {unsigned char h, l;}bytes;}i;
unsigned char n;
if(n1==0){return(0);}       // 被除数等于零返回
i.bytes.h=n1; i.bytes.l=0;  // 使用公用体变量便于字节操作
for(n=8;n>0;n--)
{
  i.w=i.w<<1;
  if(CY==0)
  {
   if(ACC  }
  else ACC=ACC-n2;
  i.bytes.h=ACC; i.bytes.l++;
}
return(i.bytes.l);
}

// ============================================================
// 功能:画直线
// 编程:臧德运
void PLine(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, bit mode)
{
unsigned char n, k;
unsigned char x, y, x0, y0;

// 修正坐标原点为左下角
y1=y1^0x7f;
y2=y2^0x7f;

// 求X坐标偏移量的绝对值
if(x2 {
  ACC=~ACC;ACC++;                       // 求绝对值
  n=x1; x1=x2; x2=n; n=y1; y1=y2; y2=n; // 校正画线方向提高效率
}
x0=ACC;

// 求Y坐标偏移量的绝对值
// 避免使用ABS函数提高效率
if(y2 y0=ACC;

x=x1; y=y1;
if(x0==y0)   // 斜率等于1时画正斜线
{
  for(n=x0;n>0;n--)
  {
   Pixel(x, y, mode); x++;
   if(y2>y1)y++;
   else y--;
  }
}
else
{
  if(x0>y0)  // 小于45度的斜线
  {
   k=Div(y0,x0);
   for(n=0;n<=x0;n++)
   {
    ACC=k;B=n;ACC=ACC*B; y0=B;
    if(ACC_7)y0++;
    if(y2>y1){y=y1+y0;}else{y=y1-y0;}
    Pixel(x1+n, y, mode);x++;
   }
  }
  else    // 大于45度的斜线
  {
   k=Div(x0,y0);
   for(n=0;n<=y0;n++)
   {
    ACC=k;B=n;ACC=ACC*B;
    if(ACC_7)B++;
    x=B+x1;
    Pixel(x, y, mode);if(y2>y1){y++;}else{y--;}
   }
  }
}
return;
}
// ============================================================
// 二(十六)进制转换为十进制
// 返回:低四位十进制编码+B(万位)
// 格式:C51
// 编程:臧德运
unsigned int bin2dec(unsigned char bl, unsigned char bh)
{
union{unsigned int i; struct{unsigned char h, l;}bytes;}d;

d.bytes.l=bl; d.bytes.h=bh;
B=0;bh=0;

// 逐次d.i-10000,不够减退出循环,循环次数就是万位值
while(1)
{
  d.i+=0xd8f0;if(!CY)break;
  B++;
}
d.i+=10000;

// 把减10000的余数转化为100进制
// bh=100进制高位
// d.bytes.l=余数,也就是100进制低位
for(bl=8;bl!=0;bl--)
{
  bh+=bh;              // 100进制高位同步左移
  d.i=d.i<<1;          // 8次位移逐次求100进位
  if(d.bytes.h>=100)   // 编译器在编译d.bytes.h>=100时,会有减100操作.
  {
   d.bytes.h=ACC;      // 比较时刻运算结果送100进制低位
   bh++;               // 100进制进位
  }
}
bl=B;  // 保护B内容

// 100进制转换为10进制
d.bytes.l=(d.bytes.h/10)<<4;
d.bytes.l=d.bytes.l|B;
d.bytes.h=(bh/10)<<4;
d.bytes.h=d.bytes.h|B;

B=bl;  // 恢复B内容
return(d.i);
}
0
回复
sdjufeng
LV.6
8
2006-03-29 23:01
我想来到这里的人,大多数都是这方面的高手,上面有这么多人发表了自己的看法,不管怎么说,真正的是非我想大家都有数.

有人感觉还是用C编写单片机程序精炼,效率也不低,甚至和汇编语言差不多.

是,用高级语言编写的程序看上去是很精简,当然这也是个优点,源程序上看不出什么问题来,但不知道他分析过编译软件生成的代码没有,有一个事实,在我们用手工编写的程序中,Ri寄存器都当成工作寄存器来使用,可是用高级语言生成的程序中,他们都成了辅助寄存器,或者说是局部变量,一个很简单的功能,本来利用几个寄存器和几条指令本地就可以处理,编译器会把有关参数装入Ri,然后调用相应的子程序,这些数据在Ri中的频繁装载,对整个程序的效率有什么样的影响,大家一想就会明白.

有的人,说起话来他就不负责任,还想拿什么车来压我,甚至举出ARM单片机来说明问题,大家知道这种单片机是一种什么样的器件啊,它是带有流水线结构的32位机,有的甚至带有协处理器,如果程序执行状遇到错误,系统会立即转入异常状态,性能直追80486.请问这些功能是最普通、最常见的哪种单片机具备的?他还不如告诉我们不能直接用汇编语言编写windows呢.

我的意思并不是否认用高级语言编写软件,我对C/VB用的都很熟练,很清楚高级语言的优点,对于高档高速器件,不应该局限于汇编上,但是对于绝大多数的使用环境,普通低档单片机是足够胜任的.是否采用高档单片机,这不光是一个器件价格的问题,器件技术是否容易掌握也是一个不可忽视的因素.对于大多数工作人员使用最多的常规器件,采用汇编语言,可以最大限度的发挥器件的性能,不论是速度还是程序空间,都是高级语言无法相比的.我想这一点是谁也不能否认的.
0
回复
sdjufeng
LV.6
9
2006-03-29 23:20
@deyun
使用C51可以写出跟asm51毫不逊色的程序,这要看编程者的水平了,看下面的例子://============================================================//功能:计算斜率//说明:被除数必须小于除数,返回(n1*256)/n2的商//编程:臧德运unsignedcharDiv(unsignedcharn1,unsignedcharn2){union{unsignedintw;struct{unsignedcharh,l;}bytes;}i;unsignedcharn;if(n1==0){return(0);}      //被除数等于零返回i.bytes.h=n1;i.bytes.l=0;  //使用公用体变量便于字节操作for(n=8;n>0;n--){  i.w=i.w
结构体用的不错.
0
回复
deyun
LV.4
10
2006-03-30 07:46
@sdjufeng
我想来到这里的人,大多数都是这方面的高手,上面有这么多人发表了自己的看法,不管怎么说,真正的是非我想大家都有数.有人感觉还是用C编写单片机程序精炼,效率也不低,甚至和汇编语言差不多.是,用高级语言编写的程序看上去是很精简,当然这也是个优点,源程序上看不出什么问题来,但不知道他分析过编译软件生成的代码没有,有一个事实,在我们用手工编写的程序中,Ri寄存器都当成工作寄存器来使用,可是用高级语言生成的程序中,他们都成了辅助寄存器,或者说是局部变量,一个很简单的功能,本来利用几个寄存器和几条指令本地就可以处理,编译器会把有关参数装入Ri,然后调用相应的子程序,这些数据在Ri中的频繁装载,对整个程序的效率有什么样的影响,大家一想就会明白.有的人,说起话来他就不负责任,还想拿什么车来压我,甚至举出ARM单片机来说明问题,大家知道这种单片机是一种什么样的器件啊,它是带有流水线结构的32位机,有的甚至带有协处理器,如果程序执行状遇到错误,系统会立即转入异常状态,性能直追80486.请问这些功能是最普通、最常见的哪种单片机具备的?他还不如告诉我们不能直接用汇编语言编写windows呢.我的意思并不是否认用高级语言编写软件,我对C/VB用的都很熟练,很清楚高级语言的优点,对于高档高速器件,不应该局限于汇编上,但是对于绝大多数的使用环境,普通低档单片机是足够胜任的.是否采用高档单片机,这不光是一个器件价格的问题,器件技术是否容易掌握也是一个不可忽视的因素.对于大多数工作人员使用最多的常规器件,采用汇编语言,可以最大限度的发挥器件的性能,不论是速度还是程序空间,都是高级语言无法相比的.我想这一点是谁也不能否认的.
是的,汇编语言的优点是代码简练,C的优点是变量跟结构清晰.
使用高级语言完全能知道编译器生成的代码方法,甚至能直接利用Ri寄存器,还甚至人为的不使用R寄存器传递变量,看下面的例子:


// =================================================
// 写数据到SPROM数据线
// 返回: ACK状态
// 编程: 臧德运
bit w24XX(unsigned char c)
{
ACC=c;               // 参数传递给A寄存器提高代码效率
for(c=8;c>0;c--)     // DJNZ R7, xxxx作循环提高效率
{
  SDA24XX=0x80 & ACC; // 让编译器使用循环左移实现数据高位送SDA?
  SCK24XX=1; _nop_(); // 插入控操作使高脉冲持续一段时间
  SCK24XX=0; _nop_();
}                    // 这里是DJNZ R7, xxxx代码
SDA24XX=1; _nop_();
SCK24XX=1; CY=SDA24XX;
_nop_(); SCK24XX=0;
Sdelay();
return(CY);
}

建议C和ASM混合使用.
0
回复
gao8051
LV.1
11
2006-04-21 12:55
C51比汇编要好用的多,这说明你对C51只是刚刚入门,一个真正的高手知道C51的每个语句能够编译成什么样的汇编指令出来,能够写的和汇编一样多的代码.
0
回复
sdjufeng
LV.6
12
2006-04-21 14:34
@gao8051
C51比汇编要好用的多,这说明你对C51只是刚刚入门,一个真正的高手知道C51的每个语句能够编译成什么样的汇编指令出来,能够写的和汇编一样多的代码.
“……能够写的和汇编一样多的代码. ”
小点声,来到这里的人都是高手啊,别人他们……
0
回复
sdjufeng
LV.6
13
2006-04-21 14:36
@gao8051
C51比汇编要好用的多,这说明你对C51只是刚刚入门,一个真正的高手知道C51的每个语句能够编译成什么样的汇编指令出来,能够写的和汇编一样多的代码.
我还是赞同deyun君的说法:
“汇编语言的优点是代码简练,C的优点是变量跟结构清晰.”
0
回复
2006-04-24 15:45
@sdjufeng
我还是赞同deyun君的说法:“汇编语言的优点是代码简练,C的优点是变量跟结构清晰.”
C语言是高级语言,里面用了很多正常人都能看懂的英语单词,汇编语言是低级的机器语言.不懂汇编的人绝对看不懂!这是C和汇编的最显著区别.至于哪个好哪个不好,我感觉没有比较的必要,因为它们适用于不同的对象.一个是人,一个是机器.
不知道这个说法对不对......:)
请大虾指正:)
0
回复
scarecrow2
LV.2
15
2007-09-06 22:46
看了这么多,说C好或者汇编好时应该有个基调.那就是需要我们的设计的系统.有的系统资源充足,实时性要求又不高,用C写好读易懂,何乐而不为?有的系统要求效率高,需要用汇编,也很好.其实汇编和C的优势劣势都显而易见.一个3000行的C语言程序,你若硬要用汇编写,也是可以的,不过打印出来只怕就是一本书了,而且如果过三个月谁让你改改软件怕也是个难事,汗啊~!但是无论你C用的多好,要与汇编比效率,总也是比不过的.感觉现在特别需要效率的地方也不是太多的,我比较喜欢的是大部分用C,特别需要效率的地方就嵌部分汇编进去.正所谓:60分万岁,多一分浪费,凡事够用就好,达到系统设计要求就是王道!!!
0
回复
whatcall
LV.5
16
2007-09-07 20:22
说句老实话,我觉得您没有体现出一个20余年单片机经历的工程师应有的见地.hotpower的话大体合乎情理您却听不进去,令人遗憾.
我想问一下,您做过的50几个含有MCU的项目中,性能最佳的是什么型号?项目中程序代码量最大的共计多少行?使用过RTOS吗?含有TCP/IP栈吗?语言之争在缺乏应用背景的条件下是毫无意义的.网上争论Java与C++,VC和Delphi的也是屡见不鲜,甚至有人好Java恶C,简直是关公战秦琼,为什么国人总是乐于争论这些不是问题的问题呢?C语言和汇编语言本不是一个层次,您的汇编子程序虽好,不过是在51汇编上可以调用罢了,其他架构的呢?我想是需要全盘改写吧.C编译器正是C高层次抽象和底层汇编的转换接口.如果还一味沉浸在51系列的汇编之中,我觉得您再无进步的可能.如果您看过开放源代码的操作系统如uC/OSII会有更深的体会,如果您对编译原理有了解也不会从您所用的C51编译器的代码效率来得出一些不正确的观点.

以上观点,就事论事,不当之处,请指教.
0
回复
sdjufeng
LV.6
17
2007-09-09 20:37
@whatcall
说句老实话,我觉得您没有体现出一个20余年单片机经历的工程师应有的见地.hotpower的话大体合乎情理您却听不进去,令人遗憾.我想问一下,您做过的50几个含有MCU的项目中,性能最佳的是什么型号?项目中程序代码量最大的共计多少行?使用过RTOS吗?含有TCP/IP栈吗?语言之争在缺乏应用背景的条件下是毫无意义的.网上争论Java与C++,VC和Delphi的也是屡见不鲜,甚至有人好Java恶C,简直是关公战秦琼,为什么国人总是乐于争论这些不是问题的问题呢?C语言和汇编语言本不是一个层次,您的汇编子程序虽好,不过是在51汇编上可以调用罢了,其他架构的呢?我想是需要全盘改写吧.C编译器正是C高层次抽象和底层汇编的转换接口.如果还一味沉浸在51系列的汇编之中,我觉得您再无进步的可能.如果您看过开放源代码的操作系统如uC/OSII会有更深的体会,如果您对编译原理有了解也不会从您所用的C51编译器的代码效率来得出一些不正确的观点.以上观点,就事论事,不当之处,请指教.
谢谢,关于你说的问题,我基本是赞同的.
讨论汇编与c的问题,确实不可能得出一个绝对的结论,这一点我在工作中也感觉到了.不可否认,C程序,按照大路性的编写方式,其效率确实是个问题,但是对于超大的程序,汇编也是难以支持的.
我最近的一个项目,用的c51,程序行数达到了3500行,单片机是ADuC841,显示器件为240128点阵液晶屏,用来显示参数和波形曲线.
在反复的应用研究中,我琢磨出了一套变通的c语言,当然在c的支持范围之内.这套变通的c语言,连乘除法运算都用自己的专用子程序,它更加贴近汇编,虽然程序行数增加了,甚至是明显增加,但是编译后的代码量却大大减小,速度也很高,在必要的时候插入汇编混合编程,查看代码,和汇编的效果基本一样.
少举几例:
-----------------------------------------
部分宏:
#define I2(v) HIGH_BYTE_OF_INT(v)
#define I1(v) LOW_BYTE_OF_INT(v)
#define L4(v) HH_BYTE_OF_LONG(v)
#define L3(v) HL_BYTE_OF_LONG(v)
#define L2(v) LH_BYTE_OF_LONG(v)
#define L1(v) LL_BYTE_OF_LONG(v)
#define L43(v) HIGH_INT_OF_LONG(v)
#define L21(v) LOW_INT_OF_LONG(v)
#define L32(v) MID_INT_OF_LONG(v)
#define DIV42(u, v) Ndivide(LOW_INT_OF_LONG(u), HIGH_INT_OF_LONG(u), v)
-----------------------------------------
//显示累计参数
//s=0,显示6位,s=1,显示8位
void DisLong(ulong alng, uchar s)
{
    uchar sh = 0;
    alng = DIV42(alng, 10000);
    L21(alng) = Ndiv21(L21(alng), 100);
    if (s)
    {
        sh = DisDigit(L1(alng) / 10, sh);
        sh = DisDigit(L1(alng) % 10, sh);
    }
    sh = DisDigit(L2(alng) / 10, sh);
    sh = DisDigit(L2(alng) % 10, sh);

    L21(alng) = Ndiv21(L43(alng), 100);
    sh = DisDigit(L1(alng) / 10, sh);
    DisDigit(L1(alng) % 10, sh);
    PutEngChar(L2(alng) / 10);
    if (dDecNums == 1)
        PutEngChar(CODE_POINT);
    PutEngChar(L2(alng) % 10);
}
上面这段分位程序,执行速度比用/100000,/10000…,/10的方式快五倍以上
------------------------------------------------
//参数加
void ParaUp1()
{
    if (!FlagParaWord)                  //单字节
    {
        if (i2Pointer == &iStartPhase)      //参考相位循环加减
            (*(uchar *)(i2Pointer))++;
        else if (*(uchar *)(i2Pointer) < LOW_BYTE_OF_INT(i2ParaLimH))
            if (i2Pointer == &iPumpDiaA || i2Pointer == &iPumpDiaB)
                HIGH_BYTE_OF_INT(*i2Pointer) += 10;
            else
                HIGH_BYTE_OF_INT(*i2Pointer)++;
    }   //这个大括号不能少略,以示下面else的对应关系
    else                                    //双字节
        if (*i2Pointer < i2ParaLimH)
            (*i2Pointer)++;
    FlagParaChanged = 1;
    DisSetPara();                           //参数更改后立即显示更新
}
------------------------------------------------
0
回复
zhouboak
LV.8
18
2009-10-24 12:48
@sdjufeng
谢谢,关于你说的问题,我基本是赞同的.讨论汇编与c的问题,确实不可能得出一个绝对的结论,这一点我在工作中也感觉到了.不可否认,C程序,按照大路性的编写方式,其效率确实是个问题,但是对于超大的程序,汇编也是难以支持的.我最近的一个项目,用的c51,程序行数达到了3500行,单片机是ADuC841,显示器件为240128点阵液晶屏,用来显示参数和波形曲线.在反复的应用研究中,我琢磨出了一套变通的c语言,当然在c的支持范围之内.这套变通的c语言,连乘除法运算都用自己的专用子程序,它更加贴近汇编,虽然程序行数增加了,甚至是明显增加,但是编译后的代码量却大大减小,速度也很高,在必要的时候插入汇编混合编程,查看代码,和汇编的效果基本一样.少举几例:-----------------------------------------部分宏:#defineI2(v)HIGH_BYTE_OF_INT(v)#defineI1(v)LOW_BYTE_OF_INT(v)#defineL4(v)HH_BYTE_OF_LONG(v)#defineL3(v)HL_BYTE_OF_LONG(v)#defineL2(v)LH_BYTE_OF_LONG(v)#defineL1(v)LL_BYTE_OF_LONG(v)#defineL43(v)HIGH_INT_OF_LONG(v)#defineL21(v)LOW_INT_OF_LONG(v)#defineL32(v)MID_INT_OF_LONG(v)#defineDIV42(u,v)Ndivide(LOW_INT_OF_LONG(u),HIGH_INT_OF_LONG(u),v)-----------------------------------------//显示累计参数//s=0,显示6位,s=1,显示8位voidDisLong(ulongalng,uchars){    ucharsh=0;    alng=DIV42(alng,10000);    L21(alng)=Ndiv21(L21(alng),100);    if(s)    {        sh=DisDigit(L1(alng)/10,sh);        sh=DisDigit(L1(alng)%10,sh);    }    sh=DisDigit(L2(alng)/10,sh);    sh=DisDigit(L2(alng)%10,sh);    L21(alng)=Ndiv21(L43(alng),100);    sh=DisDigit(L1(alng)/10,sh);    DisDigit(L1(alng)%10,sh);    PutEngChar(L2(alng)/10);    if(dDecNums==1)        PutEngChar(CODE_POINT);    PutEngChar(L2(alng)%10);}上面这段分位程序,执行速度比用/100000,/10000…,/10的方式快五倍以上------------------------------------------------//参数加voidParaUp1(){    if(!FlagParaWord)                  //单字节    {        if(i2Pointer==&iStartPhase)      //参考相位循环加减            (*(uchar*)(i2Pointer))++;        elseif(*(uchar*)(i2Pointer)
支持
0
回复
lin135
LV.5
19
2009-10-24 22:06
@zhouboak
支持
汇编用于简单成本低的程序,C语言是没法用的,低成本的单片机都是2K ROM以下的多.低成本的单片机运行速度也不会太快单片机频率以1M为主.

C语言实际上是个好东西,错在编译软件不好.他们为了通用更多的芯片,而自己又不想花太多的精力去优化编,因为好的编译软件需要付费的,大多数人用的C编译软件都是免费的,编译出来的效率不高.
0
回复
elaineliyan
LV.2
20
2009-11-21 08:30
不赞成你的看法
0
回复
xing1234
LV.6
21
2009-11-22 15:16
@elaineliyan
不赞成你的看法
1、了解汇编和编译器可能让你更好的写C.
2、几年前用小MCU做大系统时可能比较苛刻,但在当今大容量MCU面前这些相对就不太重要了.做个程序C所用的时间比汇编要少得多,这个没什么争议,时间是钱呀.
0
回复
ddmushroom
LV.4
22
2009-12-12 16:06
非常同意你的看法

我一般关键的程序都用汇编,C只写写界面控制之类的,图个方便

汇编还有个好处,拿掉注释能够连自己都看不懂,呵呵..
0
回复