.globl transform .extern strlen .extern malloc # this stuff didnt really need to be a macro but whatever .macro begin_func # regs reg size return address 16 byte align padding addi sp, sp, -112 # 12 * 8 + 8 + 8 sd ra, 104(sp) sd s0, 96(sp) sd s1, 88(sp) sd s2, 80(sp) sd s3, 72(sp) sd s4, 64(sp) sd s5, 56(sp) sd s6, 48(sp) sd s7, 40(sp) sd s8, 32(sp) sd s9, 24(sp) sd s10, 16(sp) sd s11, 8(sp) .endm .macro end_func ld ra, 104(sp) ld s0, 96(sp) ld s1, 88(sp) ld s2, 80(sp) ld s3, 72(sp) ld s4, 64(sp) ld s5, 56(sp) ld s6, 48(sp) ld s7, 40(sp) ld s8, 32(sp) ld s9, 24(sp) ld s10, 16(sp) ld s11, 8(sp) addi sp, sp, 112 ret .endm .section .text transform: begin_func # s0 = input ip pointer # s1 = input length # s2 = buffer length # s3 = buffer pointer mv s0, a0 call strlen mv s1, a0 li t0, 3 mul s2, s1, t0 # multiply input length by 3 to get maximum possible output length mv a0, s2 addi a0, a0, 1 # add space for null terminator call malloc mv s3, a0 beq s3, x0, .exit # if allocation failed exit the function mv t0, x0 # i mv t1, x0 # out_i .loop_start: bge t0, s1, .loop_end # if i == len finish looping add t2, s0, t0 # t2 = ip + i lb t3, 0(t2) # t3 has the char li t5, '.' bne t3, t5, .store_char # if the period isnt present skip adding the [ add t4, s3, t1 # t4 = buf + out_i li t6, '[' sb t6, 0(t4) # *t4 = '[' addi t1, t1, 1 .store_char: add t4, s3, t1 # t4 = buf + out_i sb t3, 0(t4) # *t4 = t3 (the current char) addi t0, t0, 1 addi t1, t1, 1 bne t3, t5, .loop_start # if the period isnt present go back to start of loop add t4, s3, t1 # t4 = buf + out_i li t6, ']' sb t6, 0(t4) # *t4 = ']' addi t1, t1, 1 j .loop_start .loop_end: addi t4, t4, 1 sb x0, 0(t4) # add null terminator .exit: mv a0, s3 # put buffer into return register end_func