I heard that with a jmp -2 we could make an infinite loop. It sounded weird but after the explanation that a relative jump would take one byte, the next instruction address (eip) would be 2 bytes less than the jmp address. So, I decided to implement that but I can't make it work.
That's my source code:
SECTION .text
global main
main:
push ebp
mov esp, ebp
jmp 0x-2
leave
ret
And used this to compile:
nasm -f elf asmloop.asm -o objasmloop.o
ld -m elf_i386 -o execasmloop -e main objasmloop.o
I also tried to use the hex value of -2 (FE) but still get segmentation fault. After all, I took a look at the disassembly with GDB:
Dump of assembler code for function main:
0x08048060 <+0>: push %ebp
0x08048061 <+1>: mov %ebp,%esp
0x08048063 <+3>: jmp 0xfffffffe
0x08048068 <+8>: leave
0x08048069 <+9>: ret
I was able to see on this dump that the actual difference between jmp address and leave address is in fact 5 bytes (it's not using the short reference jmp). But I tried with this to and the result was the same (segmentation fault). How can I perform that kind of infinite-loop?
jmp -2
will jump to the address -2 (or 0ff..fffeh
), at least in NASM.
As far as I know, the operand of a direct jump is always the target address, leaving the computation of the relative immediate, encoded in the opcode, to the assembler.
In short, jmp SHORT -2
if placed at offset 0, is assembled as EB FC
which can be seen, with a new syntax, as jmp <-4>
since 2+(-4) = -2.
If you want to craft opcodes, you need to revert to the pseudo instructions db
, dw
and so on.
If you just want to loop without a label, you can always use the $
symbol, that refer to the offset/address/counter of the current instruction/symbol.
So a jmp <-2>
is simply a jmp $
, that for a jump placed at zero is equivalent to jmp 0
and assembled as EB FE
as you expected.
Being $
a symbol, you can perform ordinary arithmetic on it: jmp $-2
is EB FC
or jmp <-4>
.
User contributions licensed under CC BY-SA 3.0