CompuServe Thread

need asm mavens' wisdom

25 messages in this thread
#25617From: Bart MathiasJul 11, 1992 3:29 AM
There are often more than one way of doing the same thing in assembly language. What's the best way to choose between them. Two examples: I recently added the following somehow unprofessional looking bit of code to a program I am working on: move.b #0,(a5)+ move.b #0,(a5)+ move.b #0,(a5)+ move.b #0,(a5)+ move.b #0,(a4)+ move.b #0,(a4)+ move.b #0,(a4)+ move.b #0,(a4)+ Theoretically I might pad the memory at A4 and A5, and use move.w or move.l, but I would rather not. Another possibility would be something like the following (which I haven't actually tried, so there may be a bug in it) moveq #3,d0 loop: move.b #0,(a5)+ move.b #0,(a4)+ dbra.s d0,loop That looks more like "programming," but I am afraid it would take maybe three times as long, and I'm in a bit of a hurry at this point in the program. Another case in point is the following two statements. It seems to me they will both have the same effect (lets asuume that status flags are irrelevant). How does one figure out which is faster (or otherwise preferable) in a case like this? andi.b #$7f,d2 vs. bclr.b #7,d2 (I started with the andi, but I'm inclined to switch to the bclr…?) – via Whap!
#25626From: SyndesisJul 11, 1992 10:02 AM
It seems like you have all the answers already: sometimes you want to optimize for speed, and want to avoid loop tests. Sometimes you don't want to waste 30 bytes doing something when 5 bytes can do it more slowly. Compiler code generator writers worry about such things all the time, where a program generates the assembly code. Sometimes compiler writers want to appeal to speed tests, sometimes to total code size. You might be surprised if you use a disassembler to view how other programmers answered this question: some programs have *miles* of unrolled loops.
#25743From: Bart MathiasJul 14, 1992 3:47 AM
Thanks, especially for suggesting disassembling some programs to see what others do. I haven't tried disassembling since about the time I was just starting to learn assembly language "for real," and scared the hell out of myself. I wonder if I'm ready to look at MEmacs and FutureSound yet? – via Whap!
#25826From: New memberJul 15, 1992 8:59 PM
You might NOT want to do a lot of disassembly. If you do you might get the idea that this or that is the way that its supposed to be. Make up \your own mind (at first) and form some opinions. Then try to find some different code and REMEMBER!!! Question authority! <grin>
#25920From: Bart MathiasJul 18, 1992 2:42 AM
I got a half-dozen samples of four different people's programming with my assembler. Then I bought Abacus' _Amiga Machine Language_. Each person's style (?) is so completely different from everyone else's that I think I am forever cured of the idea that there is one right way to do something. (Although I suspect that once assembled, the object codes wouldn't look nearly as different as the source codes do.) Still, you're right. I DON't want to do a LOT of disassembly. Neither of the disassemblers I have does commenting worth a damn! 🙂 But for some of the things I want to do, I'm going to have to compare methods with people who have done similar things. Or read books. I very much appreciate your advice. – via Whap!
#25898From: ShraddhanJul 17, 1992 4:36 PM
Bart, I agree with Jay's advice about looking at other people's programs. In my time I've seen code that is absolutely appalling. The best advice is to keep it simple, keep the code in small chunks. If you've got to jump around, don't jump more than a few lines. If a routine takes up more than a page, it's too long. Also remember, most code you see in books is written by academics, and bear in mind the good old saying "Those who can, do. Those who can't, teach." And try to be helpful to the person (you?) who is going to be trying to debug your code in a year's time. Regards, Shraddhan – via Whap! from Hertfordshire in the UK
#25825From: New memberJul 15, 1992 8:57 PM
My advise is don't worry how it "looks" and TRY to avoid overly cute programs. This alone will help you a LOT! I think that the first example is just fine. I couln't be much more clear as to what you are doing. And as far as taking up program space… Who cares! Thats what so nice about 68K machines. You don't have so much byte counting to keep everything in its segment etc.
#25647From: ShraddhanJul 11, 1992 8:37 PM
Bart, If you can _guarantee_ that A4 and A5 are pointing to even addresses, your best bet is to use move.l #0(a5)+ etc. (20 clock cycles per 4 bytes, as compared to 12 cycles per byte) I don't know why you'd rather not pad the memory to achieve this – what's a byte, after all? Your use of a loop, as you say, will be much slower. Can your assembler handle repeat loops? On mine, I can do: REPT 4 move.b #0,(a4)+ move.b #0,(a5)+ ENDR This _looks_ like a loop, but will generate code much like your original version. Personally, I prefer writing it out in full in this case, to make it clearer that I could not use a more efficient technique. As for the relative speed of ANDI vs. BCLR – my book is ambiguous (due to bad printing). If the difference was important to you, you could write a loop to execute the instruction a large number of times, and time it with a watch. I would be inclined to use the BCLR approach if the bit in question was used as a flag (using an equate for the value 7) – i.e. to match with a BSET or BTST. I would use the ANDI approach if I were merely masking out bits which I wanted zeroed. In fact, with ANDI, I might even write the value in binary (with leading zeroes) to make it clearer which bits were affected. Put another way, I would choose my coding to reflect my intention. This would help me with debugging in the future. Regards, Shraddhan – via Whap! from Hertfordshire in the UK
#25745From: Bart MathiasJul 14, 1992 3:48 AM
My reluctance to pad the memory to word or longword address comes in part from the fact that I'm not sure if all printers are like my MX-80 with GrafTrax, and willing to ignore binary zeros in character mode, and in part because I'm not sure by the time I get all the testing for padding need done I will still have saved that much time. Well, there are a number of complications… I guess I need one of those M68000 manuals with the timing diagrams. I used to see them all the time and thought I'd buy one someday. Now it's someday, and I never see them anymore. As for BCLR vs ANDI, I guess even following your guidelines I can go either way! Bit 7 is sort of a flag that means bits 0-6 are the ASCII they look like, but with a special use. But every character in a text could be so marked. So I'll flip a coin and find out what my own personal style is. 🙂 Bart – via Whap!
#25808From: ShraddhanJul 15, 1992 4:06 PM
Bart, As for BCLR vs AND I would say that if you are using a flag and modifying it or testing it with BCHG, BSET and BTST then you should use BCLR, whereas if your intention is to mask out part of some data, you should use AND. Yes, it's really a matter of personal style. If _I_ wanted to mask out the most significant bit of 8-bit ASCII, I would use AND. Regards, Shraddhan – via Whap! from Hertfordshire in the UK
#25917From: Bart MathiasJul 18, 1992 2:42 AM
Shraddhan, At the moment I can't even remember whether I went with BCLR or AND. I think I'll go with the philosophy that if it ain't broke, don't fix it, for now. I admit I have to fight back the feeling that with ANDI #7F,<ea> I'm working with 7 bits and therefore doing seven times as much work as I would with BCLR #7,<ea>, which just works on one; I'm sure this is purely human psychology and the machine hardly notices the difference. Bart – via Whap!
#25973From: ShraddhanJul 19, 1992 7:12 PM
Bart, According to my book (I think – it's badly printed), both BCLR and a byte-size AND take the same amount of time. For either instruction, the processor fetches 8 bits of data. Then it does the work – clear one of the 8 bits or mask all 8 bits. Then it writes back the 8 bits. The thing is, the 8 operations of masking a bit each take just as long as clearing one bit, because the 8 are done at the same time. So you could well say that from a philosophical point of view the processor is doing more work for an AND, and that moreover a lot of this work is wasted; however from a practical point of view there is nothing in it. On a psychological level – I wonder if the processor feels p*****d off for having to do all this extra work? Or is it just happy to have something to do? (I read somewhere a few years back that the bulk of the computing power in the world is spent in hanging around idly waiting for somebody to hit a key on the keyboard. In which case, if processors were p*****d off from having to do useless work, they would have gone on strike long ago.) And yes, I _did_ once have a computer go on strike on me – a Commodore C64 point blank refused to carry out one particular instruction. I turned the power off for a few minutes. Tried again. Still didn't work. Turned the power off for a day, two days. Still didn't work. Left it for a week. The machine relented and worked fine ever since. I swear that I'm not making this up! Regards, Shraddhan – via Whap! from Hertfordshire in the UK
#26013From: Bart MathiasJul 21, 1992 1:16 AM
Shraddhan, I knew computers could be ornery, but I didn't think you could threaten them into working right by making them think you might never bring them back to life again! Hmm… I wonder if that would work one of these times when I write move.b but the computer should very well know I really mean move.w? Bart – via Whap!
#26036From: ShraddhanJul 21, 1992 6:30 PM
Bart, Not so much a threat, more a rest cure. Regards, Shraddhan – via Whap! from Hertfordshire in the UK
#25827From: New memberJul 15, 1992 9:02 PM
Your comment brings up a request I have had for YEARS. Why WHY W H Y! won't someone make an assembler that lets you make a list file with cycle times (as an option). Then you can look over the code and make informed decisions. Looking it up in a book is better than nothing but hell! What are computers for! <smile>
#25876From: SyndesisJul 16, 1992 6:34 PM
That's an incredible idea, it seems so obvious, that's usually the mark of a useful concept. 🙂 Write to those assembler and compiler companies! This would be useful for C programmers, too – turn on assembler output and count cycles on C code! Don't forget the letters to disassembler companies, too, like the Puzzle Factory, and debuggers like Metadigm's. And what about some assembler keywords or C pragmas to mark the region of code you'd like to cycle-count, with in-line totals… Obviously, the computer can't truly cycle-count things like loops unless it knows default data values for counter registers, etc.
#25894From: Black Belt SystemsJul 17, 1992 12:29 PM
Our assemblers provide cycle times just before the mnemonic field. Unfortunately, we've only written cross assemblers to this point, 68xx series stuff. –Ben
#25899From: Matthew J. W. RatcliffJul 17, 1992 6:47 PM
Wouldn't this be something way below an assembler? Like presumably one could write a little hack in BASIC or ARexx to find the recognized mnemonic on each line, and output another file with the cycle time for that mnemonic on the equivalent line along with the source line, or at least the menmonic… how 'bout a sum also .. the hard part is typing in a table of mnemonics and times…. If someone sends me $10 I'll do it on a napkin at lunch.
#25901From: Black Belt SystemsJul 17, 1992 9:15 PM
No… The problem is in the 68xxx series, cycle times are extremely dependant upon what other instructions have run first, whether branches were taken, is it in the cache, is the cache on, etc. It's hard. –Ben
#25907From: SyndesisJul 17, 1992 10:41 PM
Hey, I had the same idea before I even read your message. 🙂 Ten dollars? Is that all you're paid in an hour?
#25905From: SyndesisJul 17, 1992 10:36 PM
Do you have a little feature that keeps a running total, too? That sounded like a nifty feature: with a directive, you could reset the counter, and it would make it easier to tally the cycles within a loop or a stretch of code, for example. Just an idea… Or maybe we can ask Larry to write an ARexx version of this, it could simply filter any assembler source code and add cycle counts.
#25923From: Black Belt SystemsJul 18, 1992 12:18 PM
John, Yes, there are pseudo-ops that total and reset the times; others that specify which particular CPU you have (for instance, the CMOS 68705 has a different cycle time for many instructions than does the less expensive NMOS part). You can also use the counter value in math expressions, and assign it to other variables, so that a loop count can be done and then you can pick back up with the count from the previous instructions above the loop. It's a nice feature. –Ben
#25921From: Bart MathiasJul 18, 1992 2:42 AM
Part of my assembler (CAPE2.5) package is a "runtime profiler" that I was hoping might be something like what you suggest. But apparently it isn't. I haven't figured out yet what it IS. – via Whap!
#25718From: Andy FinkelJul 13, 1992 5:00 PM
On the processors with caches (like the 030) unrolling a loop may not actually speed your code up…if it means your code no longer fits into the cache, then it might even slow down. andy
#25746From: Bart MathiasJul 14, 1992 3:48 AM
Thanks for your note about caching loops. 030s will be beyond me for some time yet, but I do hope to make my code available to others (at least those poor souls who picked up my AmigaBasic version). Let's see… When I find out what page of the RKM it tells how to find out if there's a cache or not, I can put in a branch to loop or not-loop routines (I _think_ I'm kidding). Bart – via Whap!