Search code examples
linuxassemblystackx86-64fasm

Is there a way to clone `n` amount of elements on the stack to the stack in x86_64 linux assembly?


Basically you can 'remove' elements from the stack by adding to rsp register n * 8, but if you try the opposite (rsp - (n * 8)) it doesn't work, which seems obvious but still

So if I push to the stack using push like this:

push 10
push 20

So the stack is basically (20; 10), how could I make it (20; 10; 20; 10) without needing to use registers (Because you're limited) or needing to repeat the push

But if it's not possible which is better to use as an alternative, repeating the push or using registers using pop and then pushing them back?


Solution

  • Assuming n and the pushed values are constant:

    • Your question is tagged with , so I presume the default operand size is currently set to 64 bits. Your push imm8 is pushing sign-extended quadwords. Unless you really need quadwords on the stack, how about putting 8 individual Byte values on the stack:
      push ((10 * 0x100 + 20) * 0x100 + 10) * 0x100 + 20
      mov [rsp + 4], dword ((10 * 0x100 + 20) * 0x100 + 10) * 0x100 + 20
      
      NB: In long mode it is not possible to just push imm32 so that rsp ≔ rsp − 4, hence the mov.
    • If you just want to avoid having the same constants over and over again:
      push 1234
      push 5678
      ; first copy
      push qword [rsp + 8]
      push qword [rsp + 8]
      ; second copy
      push qword [rsp + 8]
      push qword [rsp + 8]
      
    • For push imm8s, however, I would simply opt for the assembler’s expansion capability:
      repeat 3
          push 10
          push 20
      end repeat