I have created a rot13 program using X86,
.intel_syntax noprefix
.data
.text
.global main
# Program starts here
main:
# first argument
mov r14, [rsi + 8]
# second argument
mov r15, [rsi + 16]
# move the pointer in r15 to r13
mov r13, r15
#empty register
mov r12, 0
#counter
mov r11, 0
#spot negative
mov rbx, 0
jmp .num_check
.num_loop:
sub r15, '0'
#r12 have value now
mov r12, r15
add r13, 1
#update counter
add r11, 1
.num_check:
movzx r15, byte ptr [r13]
cmp r15, '-'
je .neg_sign
cmp r15, 0
je .single_digit
cmp r11, 1
je .double_digit
cmp r15, 0
jne .num_loop
.neg_sign:
mov rbx, r15
add r13, 1
jmp .num_check
.config_neg:
neg r12
mov r15, r12
mov r13, r14
jmp .rotate_char
.single_digit:
#spot negative sign
cmp rbx, '-'
je .config_neg
mov r15, r12
mov r13 , r14
jmp .rotate_char
.double_digit:
sub r15, '0'
mov rax, 10
imul rax, r12
mov r12, rax
#r15 is now int and not char
add r12, r15
cmp rbx, '-'
je .config_neg
mov r15, r12
mov r13, r14
jmp .rotate_char
.char_loop:
add r14, r15
#check if is over 'z'
cmp r14, 'z'
jg .over_z
#check if is under 'a'
cmp r14, 'a'
jl .under_a
mov rdi, r14
call putchar@PLT
add r13, 1
jmp .rotate_char
.under_a:
add r14, 26
mov rdi, r14
call putchar@PLT
add r13, 1
jmp .rotate_char
.over_z:
sub r14, 26
mov rdi, r14
call putchar@PLT
add r13, 1
jmp .rotate_char
.rotate_char:
movzx r14, byte ptr [r13]
cmp r14, 0
jne .char_loop
mov rdi, '\n'
call putchar@PLT
ret
The 'makefile' for this program
BIN = rotx
all:
gcc -g -O0 $(BIN).s -o $(BIN)
The input and output
For this program, I used
movzx r14, byte ptr [r13]
to get a single character and rotate it by adding or substracting , then I used
call putchar@PLT
to output a single rotated character.
Instead of outputting one character at a time, may I know how do I put the rotated character back into the same memory and outputting it at once? (rotating in place)
I know that I could put it back into the same memory by using
mov byte ptr [r13], r14b
but the program doesnt seem to work.
My attempt
.intel_syntax noprefix
.data
.text
.global main
# Program starts here
main:
# first argument
mov r14, [rsi + 8]
# second argument
mov r15, [rsi + 16]
# Convert char to num
# move the pointer in r15 to r13
mov r13, r15
#empty register
mov r12, 0
#counter
mov r11, 0
#spot negative
mov rbx, 0
jmp .num_check
.num_loop:
sub r15, '0'
#r12 have value now
mov r12, r15
add r13, 1
#update counter
add r11, 1
.num_check:
movzx r15, byte ptr [r13]
cmp r15, '-'
je .neg_sign
cmp r15, 0
je .single_digit
cmp r11, 1
je .double_digit
cmp r15, 0
jne .num_loop
.neg_sign:
mov rbx, r15
add r13, 1
jmp .num_check
.config_neg:
neg r12
mov r15, r12
mov r13, r14
jmp .rotate_char
.single_digit:
#spot negative sign
cmp rbx, '-'
je .config_neg
mov r15, r12
mov r13 , r14
jmp .rotate_char
.double_digit:
sub r15, '0'
mov rax, 10
imul rax, r12
mov r12, rax
#r15 is now int and not char
add r12, r15
cmp rbx, '-'
je .config_neg
mov r15, r12
mov r13, r14
jmp .rotate_char
.char_loop:
add r14, r15
#check if is over 'z'
cmp r14, 'z'
jg .over_z
#check if is under 'a'
cmp r14, 'a'
jl .under_a
mov byte ptr [r13], r14b
add r13, 1
jmp .rotate_char
.under_a:
add r14, 26
mov byte ptr [r13], r14b
add r13, 1
jmp .rotate_char
.over_z:
sub r14, 26
mov byte ptr [r13], r14b
add r13, 1
jmp .rotate_char
.rotate_char:
movzx r14, byte ptr [r13]
cmp r14, 0
jne .char_loop
mov rdi, r13
call putchar@PLT
mov rdi, '\n'
call putchar@PLT
ret