Difference between revisions of "General Coding Tricks"

From SizeCoding
Jump to: navigation, search
(A smaller way to point to Mode 13's screen segment)
(A smaller way to point to Mode 13's screen segment)
Line 37: Line 37:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This sets ES=9FFF (or a sufficiently high value), only one away from A000.  You can write to the screen with ES: this way as long as you are aware the segment is one paragraph (16 bytes) behind, so just increase your offset by 16 if you need exact placement.
+
This sets ES=9FFF (or a similarly high value), only one away from A000.  You can write to the screen with ES: this way as long as you are aware the segment is one paragraph (16 bytes) behind, so just increase your offset by 16 if you need exact placement.
  
 
How does this work?  Checking [[Getting_Started#.COM_file_defaults|our default register values]], we see that BX is 0 and BP is set to some 09xx value.  LES performs effective address calculations and puts the result in ES; this because BX starts out as 0, this shifts BP's starting value over and copies it to ES.
 
How does this work?  Checking [[Getting_Started#.COM_file_defaults|our default register values]], we see that BX is 0 and BP is set to some 09xx value.  LES performs effective address calculations and puts the result in ES; this because BX starts out as 0, this shifts BP's starting value over and copies it to ES.

Revision as of 01:24, 7 August 2016

Data is code, code is data

Code is nothing more than data that the CPU interprets. For example, consider this multi-byte instruction:

        mov ah,37h

This assembles to B4 37. B4 by itself isn't interesting, but 37 is the opcode for AAS. Let's say you had this code before a loop, and you needed to perform AAS at the top of a loop. Rather than put AAS at the top of the loop, you can reuse the opcode that will already be there as part of the mov ah,37 that comes before it. Just jump directly into the middle of the mov ah,37h, which will get interpreted and executed as AAS:

label:
        mov ah,37h
        ;misc. stuff
        loop label+1

The +1 specifies the jump should go to 1 byte past the actual location.

If your environment holds you back, change it

The default MCGA palette is fairly horrible, but can be size advantages to changing it: While setting a new palette costs bytes, the new palette arrangement could save you headaches down the road. For example, if your code is calculating pixel colors that fall into goofy ranges, rather than constantly adjust the colors to sane ranges (ie. aligned to powers of 2), just set the palette so that values falling into those ranges look the way you want. (This assumes you have very small ways of redefining the palette, of course.)

The above is maybe not the best example. Rewrites welcome.

Need a constant?

If you need a constant value but you're out of space, search your assembled code for a byte value you can use.

A smaller way to point to Mode 13's screen segment

Rather than mov ah,a0; mov es,ax or push word a000; pop es, try this 2-byte wonder:

les bp,[bx]

This sets ES=9FFF (or a similarly high value), only one away from A000. You can write to the screen with ES: this way as long as you are aware the segment is one paragraph (16 bytes) behind, so just increase your offset by 16 if you need exact placement.

How does this work? Checking our default register values, we see that BX is 0 and BP is set to some 09xx value. LES performs effective address calculations and puts the result in ES; this because BX starts out as 0, this shifts BP's starting value over and copies it to ES.