Skip to content

maxcnunes/learning-assembly-arm64-apple

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

learning-assembly-arm64-apple

This is a personal repository to help me learning Assembly.

This project contains notes and small program examples on Assembly programming for Apple ARM64.

Resources

Articles

Videos

Docs

Projects/Examples

ARM64 (AArch64) Reference Sheets

Not specific to ARM64 and Apple development, But still good Assembly References

Books

  • Programming with 64-Bit ARM Assembly Language

Tools

  • Compiler Explorer - To have a similar assembly output from the ones we get locally with objdump, use it with armv8-a clang compiler with options -O2 -Wall, example.

Assembly ARM64 for Apple

Assembler and Syntax

Most examples of Assembly programming on the internet use the GCC Assembler with GNU-Syntax which has a good documentation available on GNU-Syntax Arm Assembly Language Reference Guide and extensive list of resources about it. Also, they are based other CPUs than the one used by Apple (Apple silicon). That makes most of the program different then what we have here.

Since those options don't work for Apple development. We must use the Clang assembler with specific instruction set architecture for Apple processor. In this case my machine is running on Apple M1 (amr64) and has associated a "A64" instruction set .

Registers

General purpose registers

Register Size Short Description
w0-w30 32-bit (4-bytes) For 32-bit decimal data
x0-x30 64-bit (8-bytes) For 64-bit decimal data

There is also a separate set of 32 registers used for floating point and vector operations, and other sizes:

Register Size Short Description
b0-b30 8-bit (1-byte) For 8-bit decimal data
h0-h30 16-bit (2-bytes) For 16-bit decimal data
s0-s30 32-bit (4-bytes) For 32-bit single precision float number
d0-d30 64-bit (8-bytes) For 64-bit double precision float number
q0-q30 128-bit (16-bytes) For 128-bit decimal data

More details:

Registers purpose

  • x0-x7: These are general purpose registers used as input/output parameters for functions calls. If a function has more than 8 arguments, the rest of the arguments are passed through the stack.
  • x8: Used as an indirect result location register.
  • x9-x15: Temporary registers. Can be used freely within a function.
  • x16-x17: Used as intra-procedure-call scratch registers (temporary).
  • x18: Reserved by Apple to its own use. We must not use it on our programs.
  • x19-x28: Callee-saved registers. Functions must save and restore these registers if used.
  • fp (x29): Frame pointer, points to the stack base during a function call, to recover stack from calling function. It is used as base pointer to local variables on the stack per function. It won't change in a function scope and it will always hold the frame base pointer.
  • lr (x30): Link register, saves the return address at a function call. It holds the address to return to when a subroutine call completes. It actually stores the address of the instruction to execute after the function call has been completed.
  • pc: Program counter, contains address of the next instruction to be executed. It is incremented for every single instruction it runs.
  • sp: Stack Pointer, used for dynamic memory allocation, points to the next available location on the stack. When the general purpose registers are not enough, we can use this to store data in the stack. It will be updated as the data is pushed and popped out of the stack.
  • xzr: Zero register, always contains the value zero. More details.

Registers cheat sheet

Just a summary of the available registers for quick reference.

Register 8 bytes Register 4 bytes Short Description
x0-x7 w0-w7 input/output parameters for function calls
x29 (alias fp) w29 frame pointer (FP)
x30 (alias lr) w30 link register (LR)
sp wsp stack pointer (SP)
pc program counter (PC)
xzr wzr zero register

Other registers

Less used registers, but still important to mention:

  • cpsr: Current Program Status Register - doc.

Instructions

Instruction Description
b Branch the current execution into another label (function).
bl Branch link, branch and save the current position in the link register.
mov Move a value to a register
fmov Move a float value to a float register
stp Store pare of resgiers data into the stack memory
strb Store a byte into the stack memory
ldr Load data from memory to register
Condition Execution

Check out conditional execution for extensions it support such as beq, bneq, and etc.

Arithmetic operations
Instruction Description
add Add the value from 2 registers
sub Subtract the value from 2 registers
mul Multiply the value from 2 registers
udiv Divides two unsigned values

Directives

Instruction Description Absolute
.byte 8-bits (1 byte) Within the range [-128,255] only
.hword (half word) 16-bits (2 bytes) Within the range [-0x8000,0xffff] only
.word 32-bits (4 bytes) Within the range [-2^31,2^32-1] only
.single, .float 32-bits (4 bytes) Fractional, within the range [+/- 1.17 x 10^-38 to +/- 3.4 x 10^38] only
.double 64-bits (8 bytes) Fractional, within the range [+/- 2.23 x 10^-308 to +/- 1.80 x 10^308] only
.quad, .dowrd (double word) 64-bits (8 bytes) Within the range [-2^63,2^64-1] only

References:

Helpful commands

Convert decimal to hexadecimal

Numeric data is represented as hexadecimal in assembly and some times we need to convert it to decimal in order to better understand what that value represents.

Probably the simplest option to convert values between decimal and hexadecimal is using the Apple Calculator app. It has a "Programmer Mode" which can be enabled on View → Programmer (⌘3).

Another option is using the terminal, here is a command to convert 1337 decimal value to hexadecimal:

printf '%x\n' 1337
// output: 539

And the command to convert it back to decimal:

printf '%d\n' 0x539
// output: 1337

Notes

Notes is a section with notes taken from different resources. Keeping them around as reference to be used on writing my own summary later.

Glossary

  • Darwin: Apple OS: macOS, iOS, etc.
  • XNU: short for X is not Unix. Is the kernel used by Darwin based on the Mach kernel.
  • Mach-O: short for Mach object file format. It determines the order which code and data in a binary file are read into memory. Programs compiled for Darwin will have this format.

Simplest explanation about page and pageoff directives https://stackoverflow.com/a/38730184/1050818

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published