<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Thu, 10 Jun 1993 09:36:01 BST
From   : ajcd@...
Subject: m/c optimisations

From: Mik Davis <davism@...>
>
> I have a piece of machine code, written using the BASIC assembler which JUST
>fits in the memory available to it. I would like to make it smaller if I can. I
>have made all the size optimisations I can think of. I was wondering if anyone 
>out there knows of any tips which would help me to reduce the size of my 
>program in memory.
> I am not interested in speed of execution here - only in memory used.

My favourite optimisation techniques include;

1) Examine the pre-and post-conditions for each block or the program
carefully; you can often get away with branches instead of jumps by branching
on some known flag state. You can also avoid setting or clearing flags (esp.
carry) often. (For example, if you add two numbers which you know won't cause
a carry set, like an address and data size, you don't need to clear the carry
before another add, and you can BCC immediately after the code also.)

2) You can use BIT zero-page and BIT absolute (&24 and &2C) as skip 1 or 2
bytes opcodes, if you don't care about the flag state afterwards. This is
useful for a fall-through in case-like statements; e.g.

.one    LDA #1          \ entry point
        EQUB &2C        \ skip next operation
.two    LDA #2          \ entry point
        EQUB &2C        \ skip next operation
.four   LDA #4          \ entry point
        EQUB &2C
.eight  LDA #8          \ entry point
        AND mask        \ use A as a mask
        ...

This saves on 1 byte for a branch after each LDA.

3) Use negative zero-page X indexing. If you use zero-page,X indexing, the
6502 doesn't carry the address over to page one if X+zp_address is greater
than &FF. You can use this for multi-byte operations (e.g. add or subtract)
where you can't perform a CPX or CPY in between (which resets the carry
state). e.g., to add two numbers in zero page together:

        LDX #&FC        \ -4
        CLC
.add    LDA one+4,X
        ADC two+4,X
        STA three+4,X
        INX
        BNE add

4) Use the carry set and clear for adding/subtracting an extra one. For
example, to print a hexadecimal digit, you can do:

print_nibble    AND #&F         \ print nibble
                CMP #10
                BCC print_digit
                ADC #ASC"A"-ASC"0"-11 \ C is set: A+1+'A'-'0'-1 == A+'A'-'0'
print_digit     ADC #ASC"0"     \ C is always clear here
                JMP oswrch

5) Use EOR for comparisons. This has the advantage that it doesn't affect the
carry, and you can recover the data by EORing again.

a.
--
Angus Duggan, Department of Computer Science,  | Jobless, Phdless, clueless
University of Edinburgh, The King's Buildings,  | PHONE: +44(0)31 650 5126
Mayfield Road, Edinburgh EH9 3JZ, Scotland.    | INET: ajcd@...         
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>