游戏开发论坛

 找回密码
 立即注册
搜索
查看: 18587|回复: 15

C语言基本功教程系列(1)

[复制链接]

27

主题

179

帖子

259

积分

中级会员

Rank: 3Rank: 3

积分
259
发表于 2006-10-7 05:57:00 | 显示全部楼层 |阅读模式
看了那么多文章,感觉到大家学习游戏程序设计的热情.经常看到很多人提出关于openGL directX,和computer graphics的问题. 但是我个人人为, 游戏程序设计,最最最重要的还是C C++语言的基本功. 如何编写高效率,整洁,和尽可能少的Bug的代码,是成为一个游戏程序设计员的关键. 所以我开拉这个小系列,来帮C或C++语言基础不牢靠的人补补基础知识,希望能够对大家有所帮助.

至于内容嘛,我想起来什么就写什么,不一定有什么逻辑关系.毕竟我工作也很忙,只有在每个milestone完了以后才有时间干点别的. 所以这里先道歉啦.

今天就讲讲最基本的循环.

int i;
for(i = 0; i < 100; i++)
{
    // do something
}

也许很多人觉得这个代码是最简洁的了.其实不然, 还有更快速的写法.

i = 100;
do
{
// do something
}while(--j);

以下是visual studio .net 2003编译过的汇编代码.

================while loop================
    j = 10;
00411A32  mov         dword ptr [j],0Ah
    do
    {
        
    }while(--j);
00411A39  mov         eax,dword ptr [j]
00411A3C  sub         eax,1
00411A3F  mov         dword ptr [j],eax
00411A42  jne         main+29h (411A39h)



================for loop================

    for(i = 0; i < 10; i++)
00413656  mov         dword ptr ,0
0041365D  jmp         main+58h (413668h)
0041365F  mov         eax,dword ptr
00413662  add         eax,1
00413665  mov         dword ptr ,eax
00413668  cmp         dword ptr ,0Ah
0041366C  jge         main+60h (413670h)
    {

    }
0041366E  jmp         main+4Fh (41365Fh)

仔细分析就会发现while循环比for循环在每次的循环中都少一条汇编语句. 主要是因为while循环是从大到小的顺序循环,不需要和10进行比较就可以跳转.而且可以直接利用--j语句设置的符号标志进行条件判断.  

同样是循环10次,但是少一条语句还很多关键的时候很有用哦.

以上是第一章,如果有不同意见,错误或者遗漏,请谅解哦.

这个,上边是debug version的代码。偷懒被人看出来,下面给出release版本经过编译器优化的代码,优化参数 /02 /0t:
============for loop=============
:00401029          xor eax, eax
:0040102b          jmp 00401030
......
:00401030          .......
:00401035          inc eax
:00401036          cmp eax, 000000064
:00401039          jl 00401030
===========while loop============
:00401029          mov eax, 000000064
:00401030          ..........
.....
:00401035          dec eax;
:00401036          jne 00401030

106

主题

743

帖子

745

积分

高级会员

Rank: 4

积分
745
QQ
发表于 2006-10-7 19:41:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

int i;
for(i = 0; i < 100; i++)
{
    // do something
}
要写成这样子用什么语句?
00400000:mov ecx,100d
00400006:
{
    // do something
}
loop 00400006

121

主题

2029

帖子

2034

积分

金牌会员

Rank: 6Rank: 6

积分
2034
QQ
发表于 2006-10-7 22:22:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

你不会是在Debug模式下输出的汇编吧,Release下10次For应该会展开优化的。。。不过说句实在话,这种优化技术未免也太。。。。

106

主题

743

帖子

745

积分

高级会员

Rank: 4

积分
745
QQ
发表于 2006-10-7 23:59:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

能不能自己去优化?

27

主题

179

帖子

259

积分

中级会员

Rank: 3Rank: 3

积分
259
 楼主| 发表于 2006-10-8 02:28:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

LOOP只能跳转很短一段距离,而且查了下intel的文档,LOOP语句的逻辑判断比较复杂,所以在某些情况下速度慢于 dec/jnz 而dec/jnz是恒定的2个cpu clock cycle.

以下摘自intel文档

IF AddressSize = 32
THEN Count is ECX;
ELSE IF AddressSize = 64 and REX.W used
THEN Count is RCX
FI;
ELSE AddressSize = 16
THEN Count is CX;
FI;
Count ← Count ? 1;
IF Instruction is not LOOP
THEN
IF (Instruction ← LOOPE) or (Instruction ← LOOPZ)
THEN IF (ZF = 1) and (Count ≠ 0)
THEN BranchCond ← 1;
ELSE BranchCond ← 0;
FI;
ELSE (Instruction = LOOPNE) or (Instruction = LOOPNZ)
IF (ZF = 0 ) and (Count ≠ 0)
THEN BranchCond ← 1;
ELSE BranchCond ← 0;
FI;
FI;
ELSE (* Instruction = LOOP *)
IF (Count ≠ 0)
THEN BranchCond ← 1;
ELSE BranchCond ← 0;
FI;
FI;
IF BranchCond = 1
THEN
IF OperandSize = 32
THEN EIP ← EIP + SignExtend(DEST);
ELSE IF OperandSize = 64
THEN RIP ← RIP + SignExtend(DEST);
FI;
ELSE IF OperandSize = 16
THEN EIP ← EIP AND 0000FFFFH;
FI;
ELSE IF OperandSize = (32 or 64)
THEN IF (R/E)IP < CS.Base or (R/E)IP > CS.Limit
#GP; FI;
INSTRUCTION SET REFERENCE, A-M
FI;
FI;
ELSE
Terminate loop and continue program execution at (R/E)IP;
FI;

106

主题

743

帖子

745

积分

高级会员

Rank: 4

积分
745
QQ
发表于 2006-10-8 11:27:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

楼主有没有intel的中文文档,我不懂英文。
LOOP只能跳转很短一段距离?没听说过。
请问win32汇编中怎样调用DX中的函数?

27

主题

179

帖子

259

积分

中级会员

Rank: 3Rank: 3

积分
259
 楼主| 发表于 2006-10-8 11:51:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

Intel 文档原话。 只能跳转 -128 到+127的地址范围。

The target instruction is specified with a relative offset (a signed offset relative to the
current value of the instruction pointer in the EIP register). This offset is generally
specified as a label in assembly code, but at the machine code level, it is encoded as
a signed, 8-bit immediate value, which is added to the instruction pointer. Offsets of
?128 to +127 are allowed with this instruction.

中文文档没有的说。。。唉,英语英语,永远的痛呀。好好学吧。  怎么觉得要进游戏业,第一门要学的语言是英语?

187

主题

6490

帖子

6491

积分

论坛元老

团长

Rank: 8Rank: 8

积分
6491
发表于 2006-10-8 18:35:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

翻译一下,Google的翻译
教学目标与具体的补偿(但相对于署名   值指示指针的就业登记. 这部分一般   大会为标志法规定,在机法方面,由于编码   签8位立即值,指示明显增加. 抵销的   这可给127-128教学.

27

主题

418

帖子

455

积分

中级会员

Rank: 3Rank: 3

积分
455
QQ
发表于 2006-10-9 03:32:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

现在的机器翻译就是笑话制造机

18

主题

92

帖子

92

积分

注册会员

Rank: 2

积分
92
发表于 2006-10-9 22:25:00 | 显示全部楼层

Re:C语言基本功教程系列(1)

都优化到这种程度了,厉害!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-17 00:45

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表