I wanted to see if self-modifying code in assembly is possible, since .text
is read-only I thought I could put the code in .data
instead, I tried the code below.
section .text
global _start ;must be declared for linker (ld)
_start: ;tell linker entry point
mov al,3
mov rbx,cont1 ;store label cont1 in rbx so we can continue there
mov cl,byte [dec_op] ;put the opcode of the dec instruction in cl
mov byte [code],cl ;replace the inc instruction with a dec instruction
jmp code ;run the modified code
cont1:
mov byte [dat1],al ;store away the changed value
add byte [dat1],0x30 ;turn the internal numeric value into an ascii digit
mov eax,4 ;system call number (sys_write)
mov ebx,1 ;stdout
mov ecx,dat1 ;location of data
mov edx,2 ;length of data
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
dat1 db 0,0xa ;location to store output
dec_op dec al ;the dec instruction
code inc al ;code to modify
jmp rbx
The output of the above is
4
While I expected 2
, since after modifying itself, it should have a decrease instruction instead of an increase instruction. What am I doing wrong?
I'm running debian sid 64-bit and I'm compiling with:
nasm -f elf64 sm.s
ld -s -o sm sm.o