Re: A89: Which is better?


[Prev][Next][Index][Thread]

Re: A89: Which is better?




Zeljko, your examples, which you call "good code", and not what I would call
good code. Perhaps you mean "efficient code." Good code, according to my
deffinition, is first and foremost code that makes sense. Maintainabilibty
would be second, portability third, and efficiency perhaps fourth. When you
are worried about efficiency, why not use inline assembly rather than
unreadable C? I guess I have to concede that those cases may be easier to
understand in assembly, but I consider them extreme cases.

-Kevin

-----Original Message-----
From: Zeljko Juric <zjuric@utic.net.ba>
To: assembly-89@lists.ticalc.org <assembly-89@lists.ticalc.org>
Date: Wednesday, May 31, 2000 4:43 AM
Subject: Re: A89: Which is better?


>
>Hi!
>
>> I very strongly disagree with the idea of assembly being easier
>> to read than C. I think it all depends on how you write your C.
>> Good C is easy to read. Good assembly is somewhat difficult to
>> read. Bad C is impossible to read. Bad assembly is worse.
>
>Now, I will talk only about GOOD C code. Some straightforward
>operations in ASM needs ugly typecasts in C. I think that typecasts
>often leads to ugly-looking C code, but they are unavoidable.
>Suppose for example that you need to call a ROM routine which
>is located at absolute address $250000. In asm you will write
>
>jsr $250000
>
>but the only way you can do this in C is
>
>((void(*)(void))0x250000)();
>
>Now, I will be more radical, but only using a realistic example.
>Suppose that you want to copy 3840 bytes of data from address
>"buffer" to address $4c00 (LCD memory), and suppose that you
>want to call TIOS built-in function memcpy for this task. You
>know that this function is 618th entry in the TIOS jump table,
>which starts on address $c8. In assembly, you should write
>(assuming no "includes"):
>
>pea 3840 ; this is shorter than move.l #3840,-(a7)
>pea $4c00
>pea buffer
>move.l $c8,a0
>move.l (a0,618*4),a0
>jsr (a0)
>
>I think that this is very clear. But note what you need to do
>in C (this line will generate exactly the same code as assembly
>program given above):
>
>((void(*)(void*,void*,long))(*(long*)(*(long*)0xc8+618*4)))
>((void*)0x4c00,buffer,3840);
>
>which is not clear, or (a bit more compact):
>
>(*(void(**)(void*,void*,long))(*(long*)0xc8+618*4))((void*)0x4c00,buffer,38
4
>0);
>
>which is even less clear.
>
>You will say that you can simply use
>
>memcpy((void*)0x4c00,buffer,3840)
>
>But, you can do this only because "memcpy" is included in the
>TIGCCLIB library. More precise, it principally defines
>
>#define memcpy (*(void(**)(void*,void*,long))(*(long*)0xc8+618*4))
>
>so you can do this. But, if you want to call anything which is
>not defined in the library, you need to do very ugly typecasting,
>which is an example of hard-to-read GOOD code.
>
>Another example: in one my program, I need to relocate another
>executable program, starting at "cptr", which is "plen" bytes
>long. I used the following code:
>
>for(eptr=pptr=(unsigned*)(cptr+plen-4);*pptr;pptr-=2);
>while(pptr<eptr) offs=*++pptr,*(char**)(cptr+2+*++pptr)=cptr+2+offs;
>
>Easy to read? No. But this is GOOD code, and very efficient. This
>code just represents my minds when I thought about how to solve this
>problem. So, this is not code dedicated to be cryptic. This is only
>my way of solving this problem. This is so clear for me, but this is
>write-only code. Try to read and understand this. Not impossible, but
>not easy (of course, I never use such code when I teach C to my
>students).
>
>You are talking about "Hello world"? OK, you should write
>
>printf_xy(0,0,"Hello world!");
>
>where printf_xy is defined in stdio.h. But, the preprocessor will
>replace printf_xy with its REAL definition. Look how this statement
>looks like after preprocessing, assuming that you use TI-GCC with
>TIGCCLIB 2.0 (if you don't believe, use -E switch during compiling):
>
>({char __s[200];((int(*)(char*,char*,...))(*((long*)(*((long*)0xC8)
>+(0x53)*4))))(__s,"Hello world!");((void(*)(int,int,char*,int))
>(*((long*)(*((long*)0xC8)+(0x1A9)*4))))(0,0,__s,4);});
>
>OK, I will shut up now. Please, don't take this message seriously;
>it is more for fun ;-)
>
>Cheers,
>
>Zeljko Juric
>
>