亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? coding.html

?? cc65 的編譯器文檔
?? HTML
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD> <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.20"> <TITLE>cc65 coding hints</TITLE></HEAD><BODY><H1>cc65 coding hints</H1><H2>Ullrich von Bassewitz, <A HREF="mailto:uz@cc65.org">uz@cc65.org</A></H2>03.12.2000<HR><EM>How to generate the most effective code with cc65.</EM><HR><H2><A NAME="s1">1. Use prototypes</A></H2><P>This will not only help to find errors between separate modules, it will alsogenerate better code, since the compiler must not assume that a variable sizedparameter list is in place and must not pass the argument count to the calledfunction. This will lead to shorter and faster code.</P><H2><A NAME="s2">2. Don't declare auto variables in nested function blocks</A></H2><P>Variable declarations in nested blocks are usually a good thing. But withcc65, there is a drawback: Since the compiler generates code in one pass, itmust create the variables on the stack each time the block is entered anddestroy them when the block is left. This causes a speed penalty and largercode.</P><H2><A NAME="s3">3. Remember that the compiler does not optimize</A></H2><P>The compiler needs hints from you about the code to generate. When accessingindexed data structures, get a pointer to the element and use this pointerinstead of calculating the index again and again. If you want to have yourloops unrolled, or loop invariant code moved outside the loop, you have to dothat yourself.</P><H2><A NAME="s4">4. Longs are slow!</A></H2><P>While long support is necessary for some things, it's really, really slow onthe 6502. Remember that any long variable will use 4 bytes of memory, and anyoperation works on double the data compared to an int.</P><H2><A NAME="s5">5. Use unsigned types wherever possible</A></H2><P>The CPU has no opcodes to handle signed values greater than 8 bit. So signextension, test of signedness etc. has to be done by hand. The code to handlesigned operations is usually a bit slower than the same code for unsignedtypes.</P><H2><A NAME="s6">6. Use chars instead of ints if possible</A></H2><P>While in arithmetic operations, chars are immidiately promoted to ints, theyare passed as chars in parameter lists and are accessed as chars in variables.The code generated is usually not much smaller, but it is faster, sinceaccessing chars is faster. For several operations, the generated code may bebetter if intermediate results that are known not to be larger than 8 bit arecasted to chars.</P><P>When doing</P><P><BLOCKQUOTE><CODE><PRE>        unsigned char a;        ...        if ((a &amp; 0x0F) == 0)</PRE></CODE></BLOCKQUOTE></P><P>the result of the &amp; operator is an int because of the int promotion rules ofthe language. So the compare is also done with 16 bits. When using</P><P><BLOCKQUOTE><CODE><PRE>        unsigned char a;        ...        if ((unsigned char)(a &amp; 0x0F) == 0)</PRE></CODE></BLOCKQUOTE></P><P>the generated code is much shorter, since the operation is done with 8 bitsinstead of 16.</P><H2><A NAME="s7">7. Make the size of your array elements one of 1, 2, 4, 8</A></H2><P>When indexing into an array, the compiler has to calculate the byte offsetinto the array, which is the index multiplied by the size of one element. Whendoing the multiplication, the compiler will do a strength reduction, that is,replace the multiplication by a shift if possible. For the values 2, 4 and 8,there are even more specialized subroutines available. So, array access isfastest when using one of these sizes.</P><H2><A NAME="s8">8. Expressions are evaluated from left to right</A></H2><P>Since cc65 is not building an explicit expression tree when parsing anexpression, constant subexpressions may not be detected and optimized properlyif you don't help. Look at this example:</P><P><BLOCKQUOTE><CODE><PRE>      #define OFFS   4      int  i;      i = i + OFFS + 3;</PRE></CODE></BLOCKQUOTE></P><P>The expression is parsed from left to right, that means, the compiler sees'i', and puts it contents into the secondary register. Next is OFFS, which isconstant. The compiler emits code to add a constant to the secondary register.Same thing again for the constant 3. So the code produced contains a fetch of'i', two additions of constants, and a store (into 'i'). Unfortunately, thecompiler does not see, that "OFFS + 3" is a constant for itself, since it doesit's evaluation from left to right. There are some ways to help the compilerto recognize expression like this:</P><P><OL><LI>Write "i = OFFS + 3 + i;". Since the first and second operand areconstant, the compiler will evaluate them at compile time reducing the code toa fetch, one addition (secondary + constant) and one store.</LI><LI>Write "i = i + (OFFS + 3)". When seeing the opening parenthesis, thecompiler will start a new expression evaluation for the stuff in the braces,and since all operands in the subexpression are constant, it will detect thisand reduce the code to one fetch, one addition and one store.</LI></OL></P><H2><A NAME="s9">9. Use the preincrement and predecrement operators</A></H2><P>The compiler is not always smart enough to figure out, if the rvalue of anincrement is used or not. So it has to save and restore that value whenproducing code for the postincrement and postdecrement operators, even if thisvalue is never used. To avoid the additional overhead, use the preincrementand predecrement operators if you don't need the resulting value. That means,use</P><P><BLOCKQUOTE><CODE><PRE>        ...        ++i;        ...</PRE></CODE></BLOCKQUOTE></P><P>instead of</P><P><BLOCKQUOTE><CODE><PRE>        ...        i++;        ...</PRE></CODE></BLOCKQUOTE></P><H2><A NAME="s10">10. Use constants to access absolute memory locations</A></H2><P>The compiler produces optimized code, if the value of a pointer is a constant.So, to access direct memory locations, use</P><P><BLOCKQUOTE><CODE><PRE>        #define VDC_DATA   0xD601        *(char*)VDC_STATUS = 0x01;</PRE></CODE></BLOCKQUOTE></P><P>That will be translated to</P><P><BLOCKQUOTE><CODE><PRE>        lda     #$01        sta     $D600</PRE></CODE></BLOCKQUOTE></P><P>The constant value detection works also for struct pointers and arrays, if thesubscript is a constant. So</P><P><BLOCKQUOTE><CODE><PRE>        #define VDC     ((unsigned char*)0xD600)        #define STATUS  0x01        VDC [STATUS] = 0x01;</PRE></CODE></BLOCKQUOTE></P><P>will also work.</P><P>If you first load the constant into a variable and use that variable to accessan absolute memory location, the generated code will be much slower, since thecompiler does not know anything about the contents of the variable.</P><H2><A NAME="s11">11. Use initialized local variables - but use it with care</A></H2><P>Initialization of local variables when declaring them gives shorter and fastercode. So, use</P><P><BLOCKQUOTE><CODE><PRE>        int i = 1;</PRE></CODE></BLOCKQUOTE></P><P>instead of</P><P><BLOCKQUOTE><CODE><PRE>        int i;        i = 1;</PRE></CODE></BLOCKQUOTE></P><P>But beware: To maximize your savings, don't mix uninitialized and initializedvariables. Create one block of initialized variables and one of uniniitalizedones. The reason for this is, that the compiler will sum up the space neededfor uninitialized variables as long as possible, and then allocate the spaceonce for all these variables. If you mix uninitialized and initializedvariables, you force the compiler to allocate space for the uninitializedvariables each time, it parses an initialized one. So do this:</P><P><BLOCKQUOTE><CODE><PRE>        int i, j;        int a = 3;        int b = 0;</PRE></CODE></BLOCKQUOTE></P><P>instead of</P><P><BLOCKQUOTE><CODE><PRE>        int i;        int a = 3;        int j;        int b = 0;</PRE></CODE></BLOCKQUOTE></P><P>The latter will work, but will create larger and slower code.</P><H2><A NAME="s12">12. When using the ternary operator, cast values that are not ints</A></H2><P>The result type of the <CODE>?:</CODE> operator is a long, if one of the second orthird operands is a long. If the second operand has been evaluated and it wasof type int, and the compiler detects that the third operand is a long, it hasto add an additional <CODE>int</CODE> -&gt; <CODE>long</CODE> conversion for the secondoperand. However, since the code for the second operand has already beenemitted, this gives much worse code.</P><P>Look at this:</P><P><BLOCKQUOTE><CODE><PRE>        long f (long a)        {            return (a != 0)? 1 : a;        }</PRE></CODE></BLOCKQUOTE></P><P>When the compiler sees the literal "1", it does not know, that the result typeof the <CODE>?:</CODE> operator is a long, so it will emit code to load a integerconstant 1. After parsing "a", which is a long, a <CODE>int</CODE> -&gt; <CODE>long</CODE>conversion has to be applied to the second operand. This creates oneadditional jump, and an additional code for the conversion.</P><P>A better way would have been to write:</P><P><BLOCKQUOTE><CODE><PRE>        long f (long a)        {            return (a != 0)? 1L : a;        }</PRE></CODE></BLOCKQUOTE></P><P>By forcing the literal "1" to be of type long, the correct code is created inthe first place, and no additional conversion code is needed.</P><H2><A NAME="s13">13. Use the array operator [] even for pointers</A></H2><P>When addressing an array via a pointer, don't use the plus and dereferenceoperators, but the array operator. This will generate better code in somecommon cases.</P><P>Don't use</P><P><BLOCKQUOTE><CODE><PRE>        char* a;        char b, c;        char b = *(a + c);</PRE></CODE></BLOCKQUOTE></P><P>Use</P><P><BLOCKQUOTE><CODE><PRE>        char* a;        char b, c;        char b = a[c];</PRE></CODE></BLOCKQUOTE></P><P>instead.</P><H2><A NAME="s14">14. Use register variables with care</A></H2><P>Register variables may give faster and shorter code, but they do also have anoverhead. Register variables are actually zero page locations, so using themsaves roughly one cycle per access. Since the old values have to be saved andrestored, there is an overhead of about 70 cycles per 2 byte variable. It iseasy to see, that - apart from the additional code that is needed to save andrestore the values - you need to make heavy use of a variable to justify theoverhead.</P><P>As a general rule: Use register variables only for pointers that aredereferenced several times in your function, or for heavily used inductionvariables in a loop (with several 100 accesses).</P><P>When declaring register variables, try to keep them together, because thiswill allow the compiler to save and restore the old values in one chunk, andnot in several.</P><P>And remember: Register variables must be enabled with <CODE>-r</CODE> or <CODE>-Or</CODE>.</P><H2><A NAME="s15">15. Decimal constants greater than 0x7FFF are actually long ints</A></H2><P>The language rules for constant numeric values specify that decimal constantswithout a type suffix that are not in integer range must be of type long intor unsigned long int. This means that a simple constant like 40000 is of typelong int, and may cause an expression to be evaluated with 32 bits.</P><P>An example is:</P><P><BLOCKQUOTE><CODE><PRE>        unsigned val;        ...        if (val &lt; 65535) {            ...        }</PRE></CODE></BLOCKQUOTE></P><P>Here, the compare is evaluated using 32 bit precision. This makes the codelarger and a lot slower.</P><P>Using</P><P><BLOCKQUOTE><CODE><PRE>        unsigned val;        ...        if (val &lt; 0xFFFF) {            ...        }</PRE></CODE></BLOCKQUOTE></P><P>or</P><P><BLOCKQUOTE><CODE><PRE>        unsigned val;        ...        if (val &lt; 65535U) {            ...        }</PRE></CODE></BLOCKQUOTE></P><P>instead will give shorter and faster code.</P><H2><A NAME="s16">16. Access to parameters in variadic functions is expensive</A></H2><P>Since cc65 has the "wrong" calling order, the location of the fixed parametersin a variadic function (a function with a variable parameter list) depends onthe number and size of variable arguments passed. Since this number and sizeis unknown at compile time, the compiler will generate code to calculate thelocation on the stack when needed.</P><P>Because of this additional code, accessing the fixed parameters in a variadicfunction is much more expensive than access to parameters in a "normal"function. Unfortunately, this additional code is also invisible to theprogrammer, so it is easy to forget.</P><P>As a rule of thumb, if you access such a parameter more than once, you shouldthink about copying it into a normal variable and using this variable instead.</P></BODY></HTML>

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91香蕉视频黄| 欧美性色黄大片手机版| 久久国产夜色精品鲁鲁99| 亚洲最快最全在线视频| 日韩理论片网站| 亚洲三级理论片| 亚洲免费观看高清完整| 亚洲黄色性网站| 亚洲线精品一区二区三区| 亚洲成人免费视频| 日韩成人午夜电影| 韩国女主播一区| 9l国产精品久久久久麻豆| 欧洲精品在线观看| 日韩免费高清av| 久久精品亚洲国产奇米99| 国产精品家庭影院| 亚洲精品你懂的| 香蕉久久一区二区不卡无毒影院 | av不卡在线播放| 91影视在线播放| 欧美四级电影网| 精品国产免费久久| 1区2区3区精品视频| 亚洲国产sm捆绑调教视频| 美腿丝袜亚洲一区| 99精品国产99久久久久久白柏| 在线观看免费视频综合| 日韩欧美激情在线| 亚洲欧美激情在线| 久久丁香综合五月国产三级网站 | 亚洲精品乱码久久久久| 首页国产丝袜综合| 大白屁股一区二区视频| 欧美日韩国产首页| 中文字幕的久久| 日韩av不卡一区二区| 成人国产视频在线观看| 91精品国产一区二区三区蜜臀| 欧美激情在线看| 琪琪久久久久日韩精品| 一本到不卡免费一区二区| 精品成a人在线观看| 亚洲一区影音先锋| 成人精品一区二区三区中文字幕| 91精品国产一区二区三区蜜臀| 国产嫩草影院久久久久| 乱一区二区av| 欧美日韩色综合| 亚洲人精品一区| 成人高清免费在线播放| 日韩欧美卡一卡二| 亚洲一级电影视频| 99麻豆久久久国产精品免费| 日韩欧美在线影院| 亚洲va国产天堂va久久en| 99精品在线免费| 久久婷婷国产综合精品青草| 日韩高清一区二区| 欧美视频一区二区三区在线观看| 国产精品盗摄一区二区三区| 久久97超碰国产精品超碰| 欧美午夜精品理论片a级按摩| 18欧美亚洲精品| 成人av片在线观看| 国产欧美精品一区二区色综合朱莉 | 最近日韩中文字幕| 国产成人鲁色资源国产91色综 | 欧美日韩精品系列| 亚洲主播在线观看| 在线一区二区三区做爰视频网站| 国产精品热久久久久夜色精品三区 | 亚洲成人免费观看| 欧美日韩小视频| 偷拍与自拍一区| 欧美高清视频不卡网| 午夜伦欧美伦电影理论片| 欧美精品在线观看播放| 日韩综合小视频| 欧美写真视频网站| 日本不卡免费在线视频| 精品国产亚洲在线| 丰满白嫩尤物一区二区| 国产精品乱人伦中文| 99国产精品国产精品久久| 一区二区成人在线视频| 欧美视频一区二区三区四区| 日本中文一区二区三区| 欧美videossexotv100| 国产成人在线色| 亚洲欧美日韩中文字幕一区二区三区| 99re成人在线| 日韩精品亚洲一区| 国产亚洲婷婷免费| 色8久久精品久久久久久蜜| 亚洲国产成人av网| 精品日韩av一区二区| 成人一区二区三区在线观看| 一区二区三区日韩精品视频| 日韩欧美一区二区视频| 国产美女精品人人做人人爽 | 欧美一二三区在线| 成人免费视频网站在线观看| 亚洲一卡二卡三卡四卡| 欧美精品一区二区三区四区| 99久久亚洲一区二区三区青草 | 国产乱国产乱300精品| 亚洲欧美国产三级| 精品久久久久香蕉网| 99久久伊人精品| 日本美女一区二区| 国产精品第一页第二页第三页| 欧美丝袜丝nylons| 成人高清视频免费观看| 美女一区二区在线观看| 亚洲欧洲制服丝袜| 久久综合久久综合久久综合| 日本电影欧美片| 国内精品久久久久影院薰衣草| 亚洲自拍欧美精品| 欧美国产综合色视频| 欧美日韩精品一区二区天天拍小说| 国产成人精品一区二区三区四区| 亚洲国产成人va在线观看天堂| 国产视频一区在线观看| 日韩欧美激情一区| 欧美日韩电影在线播放| 99精品视频中文字幕| 国产99精品视频| 美腿丝袜亚洲色图| 三级久久三级久久| 尤物在线观看一区| 亚洲国产精品激情在线观看| 久久综合九色综合97婷婷| 91精品国产福利| 欧美美女bb生活片| 日本精品视频一区二区| 99视频精品全部免费在线| 国产精品一卡二卡| 国内精品自线一区二区三区视频| 日本少妇一区二区| 日韩中文字幕不卡| 性感美女久久精品| 婷婷综合五月天| 午夜伦理一区二区| 首页欧美精品中文字幕| 天堂va蜜桃一区二区三区漫画版| 亚洲一区二区三区影院| 亚洲精品视频观看| 一个色在线综合| 亚洲一区二区三区四区中文字幕| 亚洲三级小视频| 亚洲一线二线三线久久久| 亚洲一区二区在线观看视频 | 久久99精品国产.久久久久久| 亚洲成人在线免费| 日本午夜精品一区二区三区电影 | 99在线精品视频| 国产成人av自拍| 99国产精品99久久久久久| 一本一本久久a久久精品综合麻豆| 成人美女视频在线观看18| 成人av在线播放网站| 色老汉av一区二区三区| 精品视频1区2区| 欧美成人a视频| 国产日韩欧美麻豆| 亚洲日本乱码在线观看| 偷拍一区二区三区| 国产乱码精品一品二品| www.日韩av| 欧美三区在线视频| 日韩欧美色电影| 国产精品无人区| 亚洲观看高清完整版在线观看 | 91在线一区二区| 欧美天堂一区二区三区| 日韩欧美国产精品一区| 欧美激情一区二区三区四区| 亚洲一区二区av电影| 久久99精品久久只有精品| 成人午夜激情在线| 欧美日韩成人一区二区| 亚洲精品一区二区三区影院| 亚洲丝袜制服诱惑| 老司机免费视频一区二区 | 欧美午夜片在线看| 久久嫩草精品久久久精品| 亚洲激情中文1区| 精品一区二区三区免费| 91高清视频在线| 久久久久综合网| 亚洲一区二区在线免费看| 国产综合色产在线精品| 欧美日韩成人激情| 亚洲三级小视频| 国产激情一区二区三区四区| 56国语精品自产拍在线观看| 国产精品不卡一区二区三区| 久久国产福利国产秒拍|