Assembly language

Language processes

High-level language -> Assembly language -> Machine language -> computer

  • High-level languages: for example, Swift, Java
  • Assembly language: MOVq %rax % Rdi
  • Machine language: 1001010100101

Summary: Assembly language and machine language are one-to-one correspondence, assembly language can be compiled to get machine language, machine language can also be disassembled to get assembly language.

IOS main assembly language

  • AT&T Assembly: iOS emulator
  • ARM assembler: iOS real device

Whatever it is, it’s universal.

Common assembly instructions

  • Movq: Constant or memory assignment. For example: movq %rax, % RDX, which means to assign the rax register value to RDX. By movq %rax, 0x1fd3(% RBP), means to assign the value of rax to the memory space with address RBP + 0x1fd3.
  • Leaq: memory address. For example, leaq 0x17BD (%rip), %rdi, which means rip + 0x17BD address value assigned to RDI.
  • Callq: function. For example, callQ 0x100003AF0, the function 0x100003AF0 is entered.
  • Jump: jump. For example, JMP 0x100002703, skip to the column whose memory is 0x100002703.
  • Retq: Return. When entering callq, there is retQ to end the function.
  • Addq: addition. For example, addq % RCX, %rax, means the value of RCX plus the value of rax.

Common LLDB commands

  • Register read % Rdi, or Register read, can read the value of one register or all registers
  • Register write %rdi 0, change the rDI register value to 0
  • X /4xg 0x00000001000083E8 reads the value of 4, 8 bytes of memory
  • N or NI: the next step in source/assembly, not into subfunctions.
  • S or SI: the next step in source/assembly, which is entered when the subfunction call is encountered.
  • Finish: CAL goes inside the child function, and the child function jumps out and finishes.

Peep enumeration memory

Interview questions

enum TestEnum1 {
    case test1(Int, Int, Int)
}
print(MemoryLayout<TestEnum1>.size)
print(MemoryLayout<TestEnum1>.stride)
print(MemoryLayout<TestEnum1>.alignment)

enum TestEnum2 {
    case test1,test2,test3
}
print(MemoryLayout<TestEnum2>.size)
print(MemoryLayout<TestEnum2>.stride)
print(MemoryLayout<TestEnum2>.alignment)

enum TestEnum3 {
    case test1(Int, Int, Int)
    case test2,test3,test4
}
print(MemoryLayout<TestEnum3>.size)
print(MemoryLayout<TestEnum3>.stride)
print(MemoryLayout<TestEnum3>.alignment)
Copy the code

Guess what the print result will be and why.

Assembly analysis

enum TestEnum {
    case test1(Int, Int, Int)
    case test2(Int, Int)
    case test3(Int)
    case test4
}


var t = TestEnum.test1(1, 2, 3)
t = .test2(1, 2)
t = .test4
Copy the code

Set assembly commands: Debug->Debug Workflow -> Always Show Disassembly. Let’s make a breakpoint on the line var t = TestEnum and run the code.

Test1 (1, 2, 3), assign 1 to rip+0x5d01, 2 to rip+ 0x5CFe, 3 to rip+ 0x5CFb, and 0 to rip+ 0x5Cfc.

Let’s see how much memory the RIP register has and what its value is.

The memory address of RIP is **0x1000083D8. Of course, if we use the computer to put 0x5d01+ 0x1000026D7, we can also calculate 0x1000083D8. **x/4xg ox1000083D8: LLDB: 0x5cdd(%rip), % RDX

Movb, movB, movB, movB, movB, movB, movB, movB, movB, movB, movB, movB, movB, movB

T =.test2(1, 2); t =.test2(1, 2);

That’s why the actual memory footprint printed out is 25, and the allocated memory is 32, right

print(MemoryLayout<TestEnum>.size)//25
print(MemoryLayout<TestEnum>.stride)//32
print(MemoryLayout<TestEnum>.alignment)//8
Copy the code

Enumeration memory analysis results

For the associated value, we directly calculate the maximum associated value, if there are more than one, there is a marker bit 1 byte.

RawValue can be retrieved for raw values, which are memory free enumerated variables.