What is the difference between instructions and directives in assembly?
Instruction: Machine code mnemonic. Each instruction generates machine code that is read and executed by the CPU. Pseudo-instructions (pseudo-operations) : non-executable instructions that have no corresponding machine code and require interpretation by the assembler.
2, OS X directive:
All assembler directives (GUN general assembler directives) have names that begin with ‘. ‘ Names are mostly case insensitive and are usually represented in lowercase letters.
1. Define data pseudo (size of data type space under ARM64)
Short // Defines a variable with a size of 2 bytes. Int // Defines a variable with a size of 4 bytes. Long // Defines a variable with a size of 8 bytes The string is defined to end with a non-zero, and '\0'.asciz is added to the end of the lineCopy the code
2, assembly control (1) conditional judgment instruction:
.if /* Conditional judgment begins */.else.endif /* Conditional judgment ends */Copy the code
(2) Macro definition directives:
.macro macro name /* Start macro definition */.endMacro /* End of macro definition */Copy the code
A segment is composed of zero or more sections. The name of the segment begins with a double underscore (_) + all capital letters (e.g. The section name begins with a double underscore + all lowercase letters (for example: __DATA)
.section segName, sectName [[[, type], attribute], sizeof_stub] Example: .section __DATA __DATA // is equivalent to.data. section __TEXT __TEXT // is equivalent to.text. Section __TEXT __const // is equivalent to.const. Section __TEXT, __cString, cstring_literals // Is equivalent to.cstringCopy the code
See the OS X Assembler Directives at the end of this article for more information
Align the current position with the align_expression boundary using fill_expression (if specified, must be absolute, if not specified, zero). Align_expression is a power of 2 between 0 and 15 (for example:.align 3 means 2 ^ 3 (8) bytes aligned).
.align align_expression [, 1byte_fill_expression [, max_bytes_to_fill]] Example:.align 3 // Corresponds to 2 ^ 3 (8) bytes alignmentCopy the code
Repeat_expression must be an absolute expression greater than 0. Fill_size is in bytes and must have a value. The value can be 1,2,4 or 8. Fill_expression can be any absolute expression (it will be truncated to the fill size).
Fill repeat_expression, fill_size, fill_expression Example:. Fill 16, 1, 0Copy the code
Private_extern. Private_extern changes symbol_name to a private extern. When the link editor combines this module with other modules (and the keep_private_externs command-line option is not specified), this symbol changes it from global to static. If you use the.private_extern and.globl assembler directives on the same symbol, the effect is the same as if you only used.private_extern.
Private_extern Symbol_NAME Example. Private_extern _objc_restartableRangesCopy the code
A tag is an identifier used to mark the position of a program or data object. Each tag consists of an identifier and a terminating colon. The letters in the identifier are case sensitive.
identifier: [ identifier: ] ... Example: L_method_invoke_small:Copy the code
8. Other directives
.abort // causes the assembler to ignore further input and exit processing. Text // represents the code snipbe.data // represents the data snipbe.globl // Declare the global symbol.include // introduces the header.set // defines the symbol as an expression, The equivalent of symbol_name = absolute_expressionCopy the code
Iii. Annotation style:
1. Platform-specific one-line comments: x86-64 starts with #, arm uses it; At the beginning
Add x10, x10, #0x1 # This a comment line This a comment line: ARMCopy the code
2. GNU General Syntax (1) Multi-line comments
/* Comment code */Copy the code
(2) One-line comments
MOV R1,#15 // Load R1 with 15
Copy the code
Iv. Register
The main components of a typical CPU: arithmetic unit, controller, and register. Registers are computer memory used by the CPU to store instructions, data, and addresses. It has limited storage capacity and is the fastest read-write memory in the CPU.
1, ARM64 common registers (1) 31 general purpose registers R0-R30, each register can be accessed in the following ways:
-
When accessed through x0-X30, it is a 64-bit general-purpose register
-
When accessed through W0-W30, it is a 32-bit (accessing the lower 32 bits) general purpose register
The X30 general purpose register is used as the procedure call link register.
(2) SP: 64-bit dedicated stack pointer register, use SP/WSP to access the stack pointer register, WSP means to access the lower 32 bits of the stack pointer.
There is no register for X31 or W31. The instruction determines whether register 31 is a stack pointer or a zero register. When used as a stack pointer, it is called SP. When used as a zero register, it is called WZR in a 32-bit environment and XZR in a 64-bit environment. ZR: zero register, which reads zero when it is used as a source register and discards the result when it is used as a target register.Copy the code
(3) PC: 64-bit program counter, used to save the current instruction address. Software cannot write directly to a program counter. (4) SIMD&FP: 32 vector & floating point registers, V0-V31. Each register can be accessed as follows:
- It is a 128-bit register when accessed through Q0-Q31
- When accessed through D0-D31, it is a 64-bit (low 64-bit) register
- When accessed through S0-S31, it is a 32-bit (accessing the lower 32-bit) register
- When accessed through H0-H31, it is a 16-bit (low 16-bit) register
- When accessed through B0-B31, it is an 8-bit (accessing the lower 8-bit) register
- A 128-bit vector of the elements
For function call purposes, the universal register is divided into four groups:
- X0-x7: Parameter register used to pass parameters to a function and return a result. The return value is returned by X0.
- X9-x15: Temporary registers saved by the caller.
- X19-x29: Registers saved by the caller.
- X8,X16-X18,X29,X30: Special purpose registers
X8: Indirect result register, used to pass indirect result location, such as the function returns a large structure. X16 and X17: represents IP0 and IP1, and calls temporary registers within the procedure. X18 is a platform register reserved for use by the platform ABI X29: Frame Pointer register (FP) X30: Link register (LR)Copy the code
In the LLDB, register read allows you to view the status of each register
Five, common calculation instructions
1. Move instruction: MOV, transfer value between register and register
mov x2, x16 ; Pass the value of x16 to register x2Copy the code
2, arithmetic operation instruction: ADD (ADD), subtract (SUB)
add x1, x2, x3 ; Pass the value of x2+x3 to register x1 sub x1, x2, x3; I'm going to pass x2 minus x3 to x1Copy the code
3, logical operation instruction: AND (AND), or (ORR), exclusior (EOR)
And x1, x1, #0xf; Pass the value in x1 and 0xf in bit and after to x1 ORR x1, x1, #6; Pass the value and 6 in x1 bit and back to x1 eor x1, x1, #0xf; Pass the values in x1 and 0xf in bit xOR to x1Copy the code
4, bucket shifter operation instruction: LSL, LSR, ASR, ROR
LSL: logical left shift LSR: logical right shift ASR: arithmetic right shift ROR: circular right shiftCopy the code
5, save/fetch data instruction: STR (register loading into memory), fetch data LDR (transfer the data in memory to the register)
str x1, [sp, #0x4] ; LDR x1, [sp, #0x4]; Pass the data in address value sp+0x4 to register X1Copy the code
6, stack operation instructions: STP (push), LDP (out of the stack)
stp x0, x1, [sp, #0x4]
ldp x0, x1, [sp, #0x4]
Copy the code
7, comparison instruction: CMP, CBZ, CBNZ, TBZ, TBNZ
cmp x0,x1 ; Compare the content of X0 with the content of X1, update the condition flag according to the result, and discard the result, equivalent to Subs XZR x0, X1 CBZ x0, LGetImpMiss1; If x0 is equal to 0, jump to LGetImpMiss1 without affecting the conditional markers CBNZ x0, LGetImpMiss1; If x0 is not equal to 0, jump to LGetImpMiss1, without affecting the condition flag TBZ x0, #20, LGetImpMiss1; If the 20th bit (x0[20]) in x0 is equal to 0, then it jumps to LGetImpMiss1. This does not affect the conditional flag TBNZ x0, #20, LGetImpMiss1; If the 20th bit in x0 (x0[20]) is not equal to 0, then jump to LGetImpMiss1, without affecting the condition flagCopy the code
8, jump instruction: B: no return jump, with CMP use BL: with return jump, will return address stored in register X30, indicating that this is a subroutine call
Example 1: b LLookupExample; Use CMP x0,#6 b.q LReturnZeroExample; If x0 = 6, jump LReturnZeroExample condition code: B.q; Equal b.n e; Is not equal to B.lie; Signed less than or equal to B.ge; Signed greater than or equal to B.lt; Signed less than B.gt; Marked greater than example 3: BL lookUpFindExampleCopy the code
9, subroutine return instruction: RET (return address stored in X30)
LTestExample:
mov x2, #0
ret
Copy the code
10, addressing instruction: ADRP (PC relative address form 4KB page, namely: take the base address of the specified label, stored in the specified register)
adrp x1, __example_handle@PAGE ; Get the base address of the page where __example_handle resides and store it in register X1Copy the code
11, unsigned bit field selection instruction: UBFX (extract specified bit)
ubfx x11, x0, #60, #4 ; Extract 4 bits from the source register X0, starting at 60. Copies the 60-63 bits in X0 to the least significant bits in the target register X11 and sets the other high bits on that X11 to zeroCopy the code
6. Reference materials
- Writing ARM64 Code for Apple Platforms
- The GNU compiler
- MachO header file
- MachOView
- Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile
- ARM Cortex-A Series Programmer’s Guide for ARMv8-A
- GNU Assembler General Directive usage as User manual
- OS X Assembler Directives