flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2 |
Author |
|
Endre 18 Jul 2004, 11:15
spideros1 wrote:
If GCC compiled the code given by you then it would make an even bigger mistake than it would do producing just an error simply. It's because it doesn't know anything about your aims and thinks that you make everything correctly so it generates the faulty code as a good servant. Code: mov eax, 2 loop: inc eax cmp eax, 1 jne loop However it at least puts out a warning that something might not be correct in your for() statement. That's the problem with C. It allows almost everything. That's why C is not proper for softwares of safety critical systems. And we can declare that such a language is not proper for anything. Let's forget it. You certainly know this horror example: Code: int v[10]; v[3] = 4; /* correct */ 3[v] = 4; /* correct too */ Endre. |
|||
![]() |
|
tom tobias 18 Jul 2004, 12:40
Gomer wrote:
Write a DOS program to count to 3 in both c and asm. The C code is: for(i=1;i++;i<=3) ; ASM is: mov ax,1 :count inc ax cmp ax,3 jbe count Jarek replied: GCC generates such code: mov eax,2 .L6: dec eax jns .L6 Endre then proposed: mov eax, 2 loop: inc eax cmp eax, 1 jne loop so now we have the four blind men examining the elephant to describe the creature: one who focuses on the tusks, one the tail, etc. Starting over: The original C code, (and the accompanying ASM code) suggested by Gomer, yields a RESULT, which is placed in the variable i, and is equal to 4. The GCC compiler result proposed by spideros cannot be accurate. It does not produce a resultant value. Of course, one can argue that the purpose of the C code was simply to introduce a delay of six clock cycles (each arithmetic and logic step require a single clock cycle), NOT to produce a result placed in a variable, but absent such clarification, the proper assembly language version, MUST have a variable with the result of 4. Endre's code appears to me to resemble an infinite loop. conclusion: Whether programming in C, Asm, or any other language, one must specify, carefully, exactly what is to be accomplished. regards, tom ![]() |
|||
![]() |
|
f0dder 18 Jul 2004, 13:12
well, since 'i' isn't used after the loop, the C compiler is free to optimize the loop in any way it wants. Heck, since the loop is empty, it should have been removed completely. If you want to "count to three", make the count value "volatile", that will put a lot of restrictions on how the compiler can optimize.
|
|||
![]() |
|
Endre 18 Jul 2004, 15:28
tom tobias wrote: Gomer wrote: My code is not an infinite loop, but it runs very long until 'i' overflows (i==0). That was the main thing I wanted to point out. If you take a look at the C-code, then you may see that it really realizes an (almost ![]() The original code: Code: for(i=1;i++;i<=3) /* "infinite loop", imagine we have written this code for the computer of an aircraft, great! */ ; The code that was assumed by Jarek: Code: for(i=1;i<=3;i++) /* finite loop, we think this to be put in the computer of the aircraft -but not. */ ; So the legs of the elephant had been mixed, and only one (me) from the four blind men noticed the fact. Consequently if we want usual elephants to live around us then don't use C. Endre. |
|||
![]() |
|
f0dder 18 Jul 2004, 16:57
I noted the error, but assumed it was a typo, or an error caused by Gomer not doing a lot of C programming... so I wrote the C code correctly
![]() |
|||
![]() |
|
Gomer73 18 Jul 2004, 17:20
Actually that was a typo, thanks f0dder.
I didn't even see spideros1's code, it is interesting about the optimizing for pipelining. That looks kind of weird. If it is going to decrease anyway without caring what the variable value is, don't know why it wouldn't use a loop statement. For f0dder. That's too bad the compiler would optimize it out. I am all for optimizing, but doesn't make too much sense to take code out that I wrote. I might be wanting a delay. I think it is hilarious that I would have to add garbage statement just so it won't delete my code. But you are correct Endre as well. The code I typed was perfectly valid in C even though it was not what I intended. This is one of the reasons why I kind of dislike C. There are too many ways to do the same thing and too many things that are valid that are not meant to be. So when reading somebody else's code, you don't know if it is a bug or if that is really what they meant to do. The most common mistake I see happen is something like: if var=0 then blah,blah, blah... When what a person means is: if var==0 then blah,blah,blah... Both are totally valid and could be exactly what the programmer intended as well. However in asm, you can't really make the same mistake. Decisions, decisions. The pipelining is nice, didn't know about that. I think I like asm too because it would force somebody to think when porting something over. Very interesting, it is interesting to see how different people interpret stuff and what is of value to others. Since this is probably the wrong area to discuss this, I will probably continue this on in the OS Construction zone. |
|||
![]() |
|
f0dder 18 Jul 2004, 17:36
Quote:
GCC optimizes the loop term, but doesn't realize it can throw away the loop... btw if you actually _used_ the loop variable inside the loop, there are limits as to which optimizations can be done. Quote:
Well, if you look at it from a "logical" point of view, the loop doesn't have any effect on your program, which is why it can be optimized away. If you want to make sure the loop stays, either you do a "garbage instruction", or you declare the loop counter volatile. If I needed a waiting loop of this form, it would be for kernel programming, and I would probably use assembly to make 100% sure I get the exact timing I need. For "normal" delays, this kind of loop is pointless. Quote:
Fortunately, sensible compilers warn when they encounter something that is typically a typo or a common error. Quote:
Unless the other programmer is very lousy, you should assume he knows what he does. "Weird constructs" aren't needed very often though, so you should generally be suspicious if you see them. for(a=1;a++;a<=3) /* do_nothing */; warning C4552: '<=' : operator has no effect; expected operator with side-effect if(a=10) /* do_something */; warning C4706: assignment within conditional expression Endre's 3[v] example is nasty, but come on - how easy is it to type that by accident? |
|||
![]() |
|
pelaillo 18 Jul 2004, 19:01
f0dder wrote: Next thing, when you look at the code they write, you start suspecting _why_ they write "free" code instead of working for a company. Don't generalize or you are going to lost credibility. ![]() There are people writing junk code either in opensource or inside commercial companies. For example, I needed to work with some very specific and costly engineering programs (stress analysis and design). They do their work, but in a painful manner because its developpement implies junk code accumulation across the lifetime of the product. And you will cry at seeing their versions for windows. Companies were obbligated by customers to provide a full working windows versions in record time. The result was an unreliable and big mosaic of codes and languages. I have seen both: wonderful written opensource code and closed source also. The sad point is that they are overwhelmed by the *junk* applications in both number and userbase. The point is that does not depend on the openess. And my personal opinion is that the possibility of removing the junk is higher if the product is open. For example, I am able to adjust and improve some of the defects in those mentioned engineering products I've used every day. In some cases I've even created some interfaces for me and my colleagues to ease our work, but nothing really great because closeness and protection, mainly propietary data structures (I can reverse input data files, but not the programs themselves). Time will tell... ![]() |
|||
![]() |
|
f0dder 18 Jul 2004, 19:14
Quote:
Sorry, but it's hard not to ![]() I've seen a lot of bad GPL code, and when you combine it with the GPL dream that opensource means "high quality code", and the typically very strong opinions of GPL followers, well... *boom*. Also, "portability" often seems to mean "will work on most linux distros, can be made working on BSD, and will require massive amounts of fixing for windows or other platforms". Of course not all GPL code is like that, and there are really large amounts of bad closed software, too... but at least most closed software doesn't have the same claims open software (their marketing hype is different :p). The bottom line is: there are too many people programming who should be doing something else. Quote:
Yes, at least theoretically - but for larger projects, it is still hard, you'll have to spend a lot of time studying the code to see what is going on and how the developers think. It's too bad that so many projects don't have very good source documentation. PS: I like some ideas of opensource, but I am against the "GPL everywhere" idea. |
|||
![]() |
|
Gomer73 18 Jul 2004, 19:43
What exactly does 3[v] indicate?
|
|||
![]() |
|
crc 18 Jul 2004, 19:57
In some compilers 3[v] can mean the third element of the array named v.
|
|||
![]() |
|
Endre 18 Jul 2004, 20:09
Gomer73 wrote: What exactly does 3[v] indicate? It's exactly the same as v[3], but C allows you to write so. If you think the thing over it's evident regarding its pointer arithmetic you might think that they shan't be the same: addr1 = v + 3 * element_size addr2 = 3 + v * element_size and you expect that addr1 != addr2 (except element_size == 1) but C reshapes your expressions like this: v[3] -> *(v + 3) 3[v] -> *(3 + v) and because of pointer arithmetic they give the same result. Endre. |
|||
![]() |
|
Wishing 19 Jul 2004, 05:48
*blinks* i made this thread two days ago.... sheesh
![]() Just to defend myself ![]() I do know that the CPU cant 'really' do two things at once... What I meant to say was that I thought that the kernal's code was NOT running concurrently... IE every int that was called jumped the cpu to the kernal and then forced it to do that function without stop (non re-entrant) until it was finished... Thank you ville for pointing out that kernal side interupt based functions are re-entrant and have their own stacks and are multitasked. This cleared up many things for me... thanks to Ville for making this OS and its nice multitasking-interupt-goodness.. and for everyone else who helped clear things up. Hopefully though.. this thread seems to have helped bring up a few issues that needed to be resolved... To notify more... I have done many improvements on the code for Tinypad. I am however in the process of contacting previous coders so that code versions dont clash etc... ![]() Wishing _________________ 446f6c7068696e |
|||
![]() |
|
spideros1 19 Jul 2004, 12:34
I used such code:
Code: void test(void){ int i; for(i=0;i<3;i++) __asm__ __volatile__("# foo");} with flags -O2 -fomit-frame-pointer, and GCC produced such code: Code: test: movl $2, %eax .p2align 4,,7.L6:#APP # foo#NO_APP decl %eax jns .L6 ret code produced by gcc is correct 1st foo -> eax = 2-1 = 1 (no sign) 2nd foo-> eax = 1-1 = 0 (no sign) 3rd foo -> eax = 0-1 = -1 (sign) |
|||
![]() |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.