On further consideration, I'm wondering if when you say "you SHA the entire block", you're perhaps referring to building the Merkle Root?
In that case, yes, you would not rebuild the merkle root every time. You'd build it once, then use it to build the header, then begin the loop of:
- SHA(SHA(blockheader))
- Compare result to difficulty
- Increment nonce value in header
- REPEAT
If you've gotten through all the possible nonces and you haven't yet received a new transaction to add to the block, you need some other way to modify the header.
Most mining software handles this by adjusting the timestamp in the blockheader.
If your mining hardware is fast enough (and/or your pool is big enough), you can run into the situation where you haven't received any new transactions that you want to include AND you are unable to adjust the timestamp any further (the protocol has limitations on how much the next timestamp is allowed to vary).
In this case, you now have to modify your merkle root. You can keep track of the merkle root building hash that occured prior to the one that is in the blockheader, and then all you have to do is change the arbitrary data in the input of the coinbase transaction (generally called extranonce), finish off the merkle root and return to the loop above with timestamp adjustments again as well.