title: Caesar decoder in ARM Assembly
body: <p>As it said in the title, my objective is to write a program in C and ARM assembly that decodes a string by shifting the byte value of each character by a certain amount. The "space" character isn't shifted, instead just copied over to the resulting string. The process ends when the null-terminator is located.</p>
  
  <p>Here is my C code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  extern void init(char * encrypt);
  extern char * decrypt(char * encrypt, int shift);
  
  int main(int argc, char * argv[])
  {
      char * result;
      char encrypt[] = "GSRKVEXYPEXMSRW CSY LEZI JSYRH XLI WLMJX ZEPYI";
      int i;
  
      init(encrypt);
      for (i = 1; i &lt; 5; i++) {
          result = decrypt(encrypt, i);
          printf("Possible decrypt with shift %d: %s\n", i, result);
      }
  }
  </code></pre>
  
  <p>Here is my ARM code (this is all in one file called decrypt.s):</p>
  
  <pre><code>@ init: reserves space for the decryption
      .global init
      .text
  init: stmfd sp!, {v1-v6, lr}
      mov v1, a1
      bl strlen
      bl malloc
      bufferAddr: .fill 4, 1, 0
      str a1, bufferAddr
      @mov a2, v1
      @bl strcpy
  
      ldmfd sp!, {v1-v6, pc}
  
  @ decrypt: performs shifting of letters to decrypt string
      .global decrypt
      .text
  decrypt: stmfd sp!, {v1-v6, lr}
      mov v1, a1 @ v1 is the pointer to encrypt (string)
      ldr v2, =bufferAddr @ v2 is the pointer to result (string)
  
      loop:
          ldrb v3, [v1], #1 @ v3 is the current char (8-bit number)
  
          cmp v3, #0
          streqb v3, [v2], #1
          beq endLabel
  
          cmp v3, #32 @ check if v3 == "space"
          streqb v3, [v2], #1 @ if true, store space in result, increment
          beq loop @ if true, proceed to next char
  
          sub v3, v3, a2 @ shift v3 by shift-value
          cmp v3, #65 @ check if v3 &gt;= 65 (A)
          strgeb v3, [v2], #1 @ if true, store char in result, increment
          bge loop
  
          @ if less than A
          add v3, v3, #26 @ add 26, wrap between A-Z
          strb v3, [v2], #1 @ if true, store char in result, increment
          b loop
      endLabel:
  
      ldr a1, =bufferAddr
  
      ldmfd sp!, {v1-v6, pc}
  .end
  </code></pre>
  
  <p>The problem is, it only goes through the loop once, then it gets stuck. Sometimes it prints an error along the lines of "sim: unknown SWI..." or "unknown v6 isbn...". Or worst of all, it just prints nothing (infinite loop?)</p>
  
  <p>I'm not sure what the problem is, my logic seems to make sense.
  I read the next byte:</p>
  
  <ul>
  <li>If it's null-terminator, I put it in the resulting string as well, and end the loop.</li>
  <li>If it's space, I put the space in the resulting string, and continue the loop.</li>
  <li>If it's >= 65 (which it SHOULD be, unless Space/null-terminator), I subtract the shift-value. If the resulting value is >= 65, I put it in the resulting string. If it's &lt; 65, I add 26, then put it in the resulting string, therefore successfully wrapping to the capital letters of the alphabet.</li>
  <li>There is (should be) no other case.</li>
  </ul>
  
  <p>Yet I still get errors, or possibly an infinite loop. Any ideas?</p>