That FPS counter reads 68, or 0b01000100. I couldn't fit the game into the 8kb flash space if I included sprintf. However, I already had a function which could display an 8-bit number on the screen, in the form of a column of eight pixels. So for the FPS counter, I printed two columns with alternate pixels in different states, then a gap, followed by a column of pixels representing the number of frame updates in the previous one-second interval.
Everything is done with integers. Sine and cosine values are pulled from an array stored in flash, which consumes far less space than including math.h and doesn't require any floating point.
Of the 1024 bytes of SRAM, 512 are used as a graphics buffer for the 64x64 game area. Most of the remainder is utilised to track bullets and asteroids (not nearly as efficiently as it could be, though).
There is no delay loop. If the program has more asteroids to process, it runs more slowly. This means that as you reduce the asteroids, the remainder begin moving more quickly. This is consistent with the behaviour of the first DOS Asteroids game I ever played (I think it was EGA-Roids) which makes me wonder if they used similar logic.