1

I'm new to ARM assembly, and I'm struggling to utilize the basic arithmetic. I'm trying to create two programs, one that adds two numbers and stores the result to a register, and another that subtracts to numbers and stores the result to a register. I feel I'm pretty close but I'm not for sure and might need a bit of guidance. With these two programs I'm assuming that the numbers are stored in memory. Here's the addition program:

.global_start:
_start:
    mov r0, #1       // Moves the first number into the register r0.
    mov r1, #2       // Moves the second number into register r1.
    add r2, r1, r0   // Adds r0 and r1 and stores the result in register r2.

And here's the subtraction program:

.global_start:
_start:
    mov r0, #1       @ Moves the first number into the register r0.
    mov r1, #2       @ Moves the second number into register r1.
    sub r2, r0, r1   @ Subtracts r1 from r0 and stores the result in register r2.

These could be completely wrong, but I'm extremely new to ARM ASM! Any advice or guidance would be very helpful!

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
NightBeezy
  • 37
  • 6
  • No, `r2` is a register, not memory. Single-step this code with a debugger and you can watch register values change. Only store instructions like `str` and `stb` write to memory. Or do you mean the input numbers? Yes, they're part of the machine code of the `mov` instructions, i.e. "immediate" operands, and machine-code can only run from memory. Use a disassembler like `objdump -d` to see the machine code; the low byte might be `01` in the first `mov`, IIRC that that's where ARM machine code puts the immediate for `mov`, with shift-count bits being separate. – Peter Cordes Apr 22 '21 at 04:08
  • @Peter Cordes I think i might have worded this a bit strangely, for the purpose of the program I'm assuming that the numbers being added and subtracted are already in memory while id like to store the result to a register - if that makes any sense. Thank you for helping me thought! – NightBeezy Apr 22 '21 at 04:11
  • 1
    Oh, well then you'll want to load them with `ldr` instead of `mov`-immediate. Look at compiler output for a C program using global variables, for example. https://godbolt.org/z/oGv3MWq4a / [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) – Peter Cordes Apr 22 '21 at 04:12
  • @PeterCordes I see, so instead of mov r0, #1, i would start with ldr r0, #1, and then add them as normal? or should i keep the mov step as well and just load them with ldr first? – NightBeezy Apr 22 '21 at 04:21
  • Nope, if you want to load from memory, you need to have some data memory to load from. If you want to set a register to a constant contained in the instruction, ARM calls that `mov`. (And it's only available for a limited range of constants). There is a pseudo-instruction `ldr r1, =1` to ask the assembler to get `1` into a register somehow, either with `mov`-immediate or by creating a "literal pool" nearby (between two functions) and loading from it with a PC-relative addressing mode. Use `objdump` to see what it actually did. – Peter Cordes Apr 22 '21 at 04:34
  • Or look at compiler output some more, and note how it gets a data address into a register before loading the 2 global vars from it. (Unfilter directives to see how it defines them in `.data`, and/or google more about how to define global vars in ARM assembly.) – Peter Cordes Apr 22 '21 at 04:34

0 Answers0