Notes on assembly language programming

Copyright © 2017–2023 J. M. Spivey
Revision as of 12:02, 19 September 2022 by Mike (talk | contribs) (Created page with "On a RISC-style machine like the ARM, we can introduce elements of assembly language in an incremental way, slowly expanding the range of operations we can express. We can be...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

On a RISC-style machine like the ARM, we can introduce elements of assembly language in an incremental way, slowly expanding the range of operations we can express.

We can begin with a single subroutine within a larger program, which can for practicality be written in C. Our first subroutines will be leaf routines that satisfy a number of simplifying assumptions:

  • Leaf routines do not call any others: hence the name, because they occupy the position of leaves in the tree of subroutines and their callers.
  • Leaf routines have at most four parameters and one result.
  • Leaf routines use only a restricted set of registers, r0 to r3.
  • Leaf routines use no storage in the subroutine stack.

Subroutines that obey these restrictions are quite common in many programs, and the conventions of the ARM allow them to be implemented in a particularly simple and efficient way.

Our first subroutines perform a straight-line sequence of operations. Inputs arrive in registers, they are combined with each other to form intermediate results held in registers, and whatever value is left in a specific register becomes the result returned by the subroutine.

Next, we move on to subroutines that contain conditionals and loops, implemented using conditional and unconditional branches.

The next level of complexity breaks out of the restrictions that apply to leaf routines. By saving the values of some registers when the subroutine is entered, and restoring them just before it exits, we can remove the restrictions and still write subroutines that cooperate smoothly with others. These register values are saved in a dedicated area of memory known as the subroutine stack, or just the stack.

  • The program address to which the subroutine should return is placed in the link register lr as part of the mechanism of calling it. By saving the incoming value of lr in the stack, a subroutine can arrange to remember its return address even if the lr register is overwritten when the subroutine calls others.
  • Subroutines that have more than four parameters can be accommodated by passing additional parameters on the stack. We shall never need to do this during the course, but it is good to know it is possible.
  • Each subroutine must preserve the values of registers r4 to r7 (and some others), but these registers become available for use if they are saved and restored. If the subroutine calls others, then it benefits from their promise to preserve any values it keeps in these registers.
  • In addition to saving the values of incoming registers in the stack, a subroutine can also adjust the stack pointer register sp to allocate some space in the stack for its own use. This storage can be addressed using offsets relative to sp, using the load and store instructions that we shall meet later.

The interface between a subroutine and those it calls is defined partly by hardware, and partly by conventions that are agreed between all the programmers who write software for the machine. For example, the fact that the return address of a subroutine is put in the lr registers is determined by the fact that the branch-and-link instruction bl (by which a subroutine is called) puts in lr the address of the next following instruction in the caller. On the other hand, it is a matter of convention that a subroutine may freely use registers r0 to r3 but must preserve any values its caller is keeping in registers r4 to r7.

The subroutine stack is stored in RAM, so that memory is accessed implicitly by the push and pop instructions that begin and end a non-leaf subroutine. There are also instructions that access RAM explicitly