tsoding / pinpog

Ping-Pong-like game in Assembly that works without OS
MIT License
571 stars 36 forks source link

Save 9 bytes by optimizing the bar-to-wall collision handling. #56

Closed edorfaus closed 5 years ago

edorfaus commented 5 years ago

Just in case it's not clear (and for future reference in case I forget), I'll try to explain my reasoning and how I ended up with this diff.

The initial observation was that the same variable is set by both branches, and one of them uses the AX register (which means it can safely be used before the code that sets it) - so I thought it should be possible to simplify by also setting AX before the first jle, and then always setting the variable to AX.

As the target value for the first branch is 0, I clear AX by using xor ax, ax since that's a byte shorter than mov ax, 0.

I then found that I could save another byte by using AX (which is now 0) in the following cmp instruction instead of using the immediate value, so I did that too. At this point I had saved 7 bytes and made the PR.

Then I looked closer at what the movzx instruction is doing, and realized that since AX is already 0 at that point, we can get the same effect by setting AL with a simple mov, which saves another two bytes, for a total of 9 bytes saved. (So I updated the PR.)

If I remember correctly from the stream, adding the snapping originally took 11 bytes; with this optimization that's down to 2 bytes. :)

rexim commented 5 years ago

@edorfaus oh, wow! That is super clever! Thank you very much for such a cool contribution!