Question: I'm new to ARM assembly and am trying to translate some easy code snippets from C to assembly. I'm not sure if I am using ldr and str correctly (although I feel like ive tried everything) and I keep getting seg fault when I try to run it.

The C code is

```
int main() {
    int x = 10;
    int y = 5;
    int z = 20;

    int min = y;

    if (x < min) {min = x;}
    if (z < min) {min = z;}

    return min;
}

```

My assembly code:

```
.global main
.text

main:
    push {ip, lr}

    mov r0, #10
    mov r1, #5
    mov r2, #20

    str r3, [r1]

    cmp r0, r3
    bge done
    str r0, [r3]

    cmp r2, r3
    bge done
    str r2, [r3]

done:
    ldr r0, [r3]
    pop {ip, pc}

```

Answer: 
OK, for each of your variables, you have to decide where you are going to store it:

* you can store it in a register, which is OK as long as you have enough spare registers;
* you can store it at a fixed address, which is fine for global and static variables but no good for local variables;
* you can store it on the stack, which is where local variables are generally stored if there aren't enough registers to go round. This is more work, as you have to load it and store it every time you want to access it.

Your function is mixing these up disastrously. You store `x,y,z`, in registers `r0,r1,r2`, but then you treat `y` as if it was stored at the address `5`, whereas it is in fact stored in the register `r1`. You don't want to use the memory access instruction `str r3, [r1]` here, because nothing is in memory; just `mov r3,r1` is enough.

The rest of the code is similarly dysfunctional, but I won't go into details. Your function is simple enough that you have more than enough registers to go round, so I suggest you re-write it to use registers for all variables. No `ldr/str` instructions at all, just `mov` instructions.

And look at the assembly code generated by your C compiler to get a feel for more complicated situations where some or all variables have to be stored on the stack.

Good luck!
TonyK's [answer](https://stackoverflow.com/a/53347221/605307) covers the source of your mistakes pretty well. It strikes me that it might benefit you to see how a *compiler* would deal with the compilation of a simple program like this; seeing the compiler allocate space on the stack for these variables, and seeing how it uses `LDR` and `STR` correctly, could well help you to learn.

If you're using gcc, try adding `-S -O1` to the compiler options to enable mild optimisation (`-O1`) and to request assembly language as the output (`-S`). The output will interleave the original C code into the generated assembly language, which will hopefully make it easier to understand.