You can use the same assembler instruction mnemonics as you'd use with any other AVR assembler. And you can write as many assembler statements into one code string as you like and your flash memory is able to hold.

To make it more readable, you should put each statement on a seperate line:

asm volatile("nop\n\t"
             "nop\n\t"
             "nop\n\t"
             "nop\n\t"
             ::);

The linefeed and tab characters will make the assembler listing generated by the compiler more readable. It may look a bit odd for the first time, but that's the way the compiler creates it's own assembler code.

You may also make use of some special registers.

Symbol

Register

__SREG__

Status register at address 0x3F

__SP_H__

Stack pointer high byte at address 0x3E

__SP_L__

Stack pointer low byte at address 0x3D

__tmp_reg__

Register r0, used for temporary storage

__zero_reg__

Register r1, always zero

Register r0 may be freely used by your assembler code and need not be restored at the end of your code. It's a good idea to use __tmp_reg__ and __zero_reg__ instead of r0 or r1, just in case a new compiler version changes the register usage definitions.