memory - MIPS program to replicate itself? -


how can create mips program such in main function prints out version1 , copies entire code memory , finaly executes copied version. copied version of code must print version2. cannot add in data section other version1 , version2.

how copy entire code memory , execute it? i've never done before don't know start.

.data    version1:    .asciiz   "this version1"    version2:    .asciiz   "this version2"  main:     li $v0, 4     la $a0, version1     syscall     #(how copy code , execute it?????) 

the ability self modify code dependent on environment of execution.
mars option can enabled. code assume little endianness data memory (no assumption code memory).

what professor want this:

  1. that recognize la pseudo instruction made of ori , lui correctly count instruction copied four.
  2. that reserve space in program flow 4 instructions using nop.
  3. that recognize instruction format edit operands.

the copy process simple. can aided assembler cleaver use of labels: put label right after code copy (and right before if there none) , copy data between these two.
since know length of code copy , small, can copy hand.

in order modify copied code need see how likes machine code

addiu $v0, 0, 4      #24020004 lui $at, hhhh        #3c01hhhh ori $a0, $at, llll   #3424llll syscall              #0000000c 

as can see have replace lower hw of 2nd , 3rd instruction.
value use address of version2.
upper , lower hw of address can obtained basic bits manipulations.

you have add code terminate program nicely.

here intentional simplified working example made mars (activate self modify code in settings).

.data    version1:    .asciiz   "this version1"    version2:    .asciiz   "this version2"  .text  main:     li $v0, 4               #1 instruction  addiu $v0, $0, 4     la $a0, version1            #2 instructions lui $a0,  h  ori $a0, l     syscall             #1 instruction      #load src , dest address     la $t0, main     la $t1, new_code      #copy 4 words of code     lw $t2, ($t0)     sw $t2, ($t1)     lw $t2, 4($t0)     sw $t2, 4($t1)     lw $t2, 8($t0)     sw $t2, 8($t1)     lw $t2, 0xc($t0)     sw $t2, 0xc($t1)      #load address of version2     la $t0, version2      add $t2, $0, $0      lui $t2, 0xffff     #t2 = 0ffff0000h      andi $t3, $t0, 0xffff       #t3 = lower hw of address     srl $t0, $t0, 0x10      #t0 = upper  hw of address      #edit ori $a0, l     lw $t4, 8($t1)      #load instruction in register     , $t4, $t4, $t2       #clear lower hw     or $t4, $t4, $t3        #set lower hw      sw $t4, 8($t1)      #save instruction      #edit lui $a0, h     lw $t4, 4($t1)      #load instruction in register     , $t4, $t4, $t2       #clear lower hw     or $t4, $t4, $t0        #set lower hw      sw $t4, 4($t1)      #save instruction   new_code:     nop     nop     nop     nop      li $v0, 10     syscall 

if interested in more generic version dynamically allocate memory (with syscall 9), align returned pointer, copy code, modify , add call syscall 10, here is

.data    version1:    .asciiz   "this version1"    version2:    .asciiz   "this version2"  .text  main:  __copy_start__:                 #sign start of code copy     li $v0, 4               #1 instruction addiu $v0, $0, 4     la $a0, version1            #2 instruction2 lui $a0,  h  ori $a0, l     syscall             #1 instruction __copy_end__:      li $v0, 9               #allocate buffer     li $a0, 27              #16 bytes (4 instructions) + 8 bytes (2 instructions) + 3 byte aligning     syscall                       #align pointer consuming first bytes (this not needed, completeness)     addi $v0, $v0, 3                 andi $v0, $v0, 0xfffffffc      #prepare copy     la $t0, __copy_start__      #t0 = source start     la $t1, __copy_end__        #t1 = source end (exclusive)     add $t2, $0, $v0            #t2 = destination start     ori $t4, $0, 1          #t4 = 1: code copied 0: code copied  do_copy:     #move source dest     lw $t3, ($t0)                sw $t3, ($t2)      #increment pointers     addi $t0, $t0, 4     addi $t2, $t2, 4      #if not reached source end, copy again     bne $t0, $t1, do_copy      #copy done     #if code has been copied, jump new code     beqz $t4, do_jump      #extra code need copied     la $t0, __copy_extra__      #new source start     la $t1, __copy_extra_end__      #new source end     add $t4, $0, $0         #signal code being copied      #copy again b do_copy                 do_jump:         #get address of version2     la $t0, version2      #save low half word low halfword of 3rd instruction (ori $a0, l)     sh $t0, 8($v0)     #get upper hw in lower hw of $t0     srl $t0, $t0, 16     #save high half word low hw of 2nd instruction (lui $a0, h)     sh $t0, 4($v0)      #jump indirect     jr $v0      #extra code append end of new code __copy_extra__:     li $v0, 10     syscall __copy_extra_end__:    

Comments

Popular posts from this blog

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -

YouTubePlayerFragment cannot be cast to android.support.v4.app.Fragment -