while(1) loop blocks program to enter interrupt
The while loop should have no effect on interrupts. Where does run() get called? We'll need to see the code that sets up and calls the code you've shown. But as a sanity check, you could try replacing the entire contents of run() with a ;, that is make it an empty function. Then add in an empty while loop (contains only a ;, no __asm__ code) and try again. Then replace the body of the while loop with __asm("nop")__ and try again. At which of the above steps does your interrupt fail? That should lead you in the right direction.

Update:
What does your main() function do after display_init() returns? Because that won't ever happen when run() runs forever. 

The job of main() is to create the C/C++ run-time environment. That may not have been completed (enabling interrupts, for instance) when display_init() and run() get called, but gets completed shortly after they returns - if run() is allowed to end.

Without seeing your main(), we can't know enough to be more specific, but I'd suggest you move all of your code out of main() and down into the Arduino setup() function because, by the time it gets called, the run-time environment will be complete.

Update 2:


  to avoid unnecessary code


If that is your entire main() function, you've left out the run-time environment setup and it's little wonder that your code behaves strangely. You've asked for help and we've made some suggestions: to show your entire code, not just selected pieces of it; and run your code in a standard way and let us know the result. Then you can optimize your code if you feel it's worth it to you. When you've done that test, and you still have questions, ask again. Until then, you're just asking us to guess. We did that. Once.