mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-23 01:16:51 +08:00
WTF was I thinking before?
This commit is contained in:
parent
c020675cd7
commit
697a9c0e87
6 changed files with 190 additions and 160 deletions
|
|
@ -4,9 +4,9 @@ Given:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct Foo {
|
struct Foo {
|
||||||
short a;
|
short a;
|
||||||
char b;
|
char b;
|
||||||
int c;
|
int c;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc };
|
struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc };
|
||||||
|
|
@ -15,62 +15,68 @@ struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc };
|
||||||
Here is [one](./test02_companion1.s) way of defining and accessing the struct:
|
Here is [one](./test02_companion1.s) way of defining and accessing the struct:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.global main // 1
|
#include "apple-linux-convergence.S" // 1
|
||||||
.text // 2
|
// 2
|
||||||
.align 2 // 3
|
GLABEL main // 3
|
||||||
// 4
|
.text // 4
|
||||||
main: // 5
|
.p2align 2 // 5
|
||||||
str x30, [sp, 16]! // 6
|
// 6
|
||||||
// 7
|
MAIN // 7
|
||||||
ldr x0, =fmt // 8
|
PUSH_P x29, x30 // 8
|
||||||
ldr x1, =Bar // 9
|
mov x29, sp // 9
|
||||||
ldrh w2, [x1] // 10
|
// 10
|
||||||
ldrb w3, [x1, 2] // 11
|
LLD_ADDR x0, fmt // 11
|
||||||
ldr w4, [x1, 4] // 12
|
LLD_ADDR x1, bar // 12
|
||||||
bl printf // 13
|
ldrh w2, [x1, 0] // 13
|
||||||
// 14
|
ldrb w3, [x1, 2] // 14
|
||||||
ldr x30, [sp], 16 // 15
|
ldr w4, [x1, 4] // 15
|
||||||
mov w0, wzr // 16
|
#if defined(__APPLE__) // 16
|
||||||
ret // 17
|
PUSH_P x3, x4 // 17
|
||||||
// 18
|
PUSH_P x1, x2 // 18
|
||||||
.data // 19
|
CRT printf // 19
|
||||||
// 20
|
add sp, sp, 32 // 20
|
||||||
fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" // 21
|
#else // 21
|
||||||
|
CRT printf // 22
|
||||||
|
#endif // 23
|
||||||
|
POP_P x29, x30 // 24
|
||||||
|
mov w0, wzr // 25
|
||||||
|
ret // 26
|
||||||
|
// 27
|
||||||
|
.data // 28
|
||||||
|
// 29
|
||||||
|
fmt: .asciz "%p a: 0x%lx b: %x c: %x\n" // 30
|
||||||
|
bar: .short 0xaaaa // 31
|
||||||
|
.byte 0xbb // 32
|
||||||
|
.byte 0 // padding // 33
|
||||||
|
.word 0xcccccccc // 34
|
||||||
|
// 35
|
||||||
|
.end // 36
|
||||||
```
|
```
|
||||||
|
|
||||||
It would be understandable if you don't see where the `struct` is being
|
It would be understandable if you don't see where the structure of the
|
||||||
defined. That's because it isn't. Rather, the implied +0 on `line 10` and
|
`struct` is being specified in the code. That's because it isn't.
|
||||||
the 2 and 4 on `lines 11` and `12` are the hard coded offsets into the
|
Rather, focus on the 0, 2 and 4 on lines 30 through 32. These are the
|
||||||
`struct`.
|
hard coded offsets of the struct's fields `a`, `b` and `c`.
|
||||||
|
|
||||||
[Here](./test02_companion2.s) is a second way to define a `struct`.
|
A second way to define the offsets of the fields within a struct which
|
||||||
|
is preferable to the one above is excerpted here.
|
||||||
|
|
||||||
|
|
||||||
|
The full text of the file is located
|
||||||
|
[here](./test02_companion2.s).
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.global main // 1
|
.equ foo_a, 0 // like #define
|
||||||
.text // 2
|
.equ foo_b, 2 // like #define
|
||||||
.align 2 // 3
|
.equ foo_c, 4 // like #define
|
||||||
// 4
|
```
|
||||||
.equ foo_a, 0 # like #define // 5
|
|
||||||
.equ foo_b, 2 # like #define // 6
|
and here:
|
||||||
.equ foo_c, 4 # like #define // 7
|
|
||||||
// 8
|
```text
|
||||||
main: // 9
|
ldrh w2, [x1, foo_a]
|
||||||
str x30, [sp, 16]! // 10
|
ldrb w3, [x1, foo_b]
|
||||||
// 11
|
ldr w4, [x1, foo_c]
|
||||||
ldr x0, =fmt // 12
|
|
||||||
ldr x1, =Bar // 13
|
|
||||||
ldrh w2, [x1, foo_a] // 14
|
|
||||||
ldrb w3, [x1, foo_b] // 15
|
|
||||||
ldr w4, [x1, foo_c] // 16
|
|
||||||
bl printf // 17
|
|
||||||
// 18
|
|
||||||
ldr x30, [sp], 16 // 19
|
|
||||||
mov w0, wzr // 20
|
|
||||||
ret // 21
|
|
||||||
// 22
|
|
||||||
.data // 23
|
|
||||||
// 24
|
|
||||||
fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" // 25
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This method uses `.equ` to make the offsets into symbolic constants.
|
This method uses `.equ` to make the offsets into symbolic constants.
|
||||||
|
|
@ -78,45 +84,28 @@ This is just like using `#define` in C and C++. That is, the above is
|
||||||
equivalent to the following in C or C++:
|
equivalent to the following in C or C++:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define foo_a 0
|
#define foo_a 0
|
||||||
#define foo_b 2
|
#define foo_b 2
|
||||||
#define foo_c 4
|
#define foo_c 4
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, [here](./test02_companion3.s) is a third way of defining `structs`.
|
Finally, [here](./test02_companion3.s) is a third way of defining
|
||||||
|
`structs`. However, this method works on Linux but not on Apple. We have
|
||||||
|
not yet discovered the incantation that allows something like this on
|
||||||
|
Apple.
|
||||||
|
|
||||||
|
The salient Linux-only code is excerpted below:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
.global main // 1
|
.section Foo
|
||||||
.text // 2
|
.struct 0 // a starts at 0 and goes for 2
|
||||||
.align 2 // 3
|
Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2
|
||||||
// 4
|
Foo.b: .struct Foo.b + 2 // c starts at 4
|
||||||
main: // 5
|
Foo.c:
|
||||||
str x30, [sp, 16]! // 6
|
|
||||||
// 7
|
|
||||||
ldr x0, =fmt // 8
|
|
||||||
ldr x1, =Bar // 9
|
|
||||||
ldrh w2, [x1, Foo.a] // 10
|
|
||||||
ldrb w3, [x1, Foo.b] // 11
|
|
||||||
ldr w4, [x1, Foo.c] // 12
|
|
||||||
bl printf // 13
|
|
||||||
// 14
|
|
||||||
ldr x30, [sp], 16 // 15
|
|
||||||
mov w0, wzr // 16
|
|
||||||
ret // 17
|
|
||||||
// 18
|
|
||||||
.section Foo // 19
|
|
||||||
.struct 0 // a starts at 0 and goes for 2 // 20
|
|
||||||
Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2 // 21
|
|
||||||
Foo.b: .struct Foo.b + 2 // c starts at 4 // 22
|
|
||||||
Foo.c: // 23
|
|
||||||
// 24
|
|
||||||
.data // 25
|
|
||||||
// 26
|
|
||||||
fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" // 27
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This method has a *substantial* benefit over the previous methods. Imagine
|
This method has a *substantial* benefit over the previous methods.
|
||||||
you need to insert a new field between `Foo.a` and `Foo.b`. Simply do so.
|
Imagine you need to insert a new field between `Foo.a` and `Foo.b`.
|
||||||
If you're using this third method, which is based on relative offsets, the
|
Simply do so. If you're using this third method, which is based on
|
||||||
assembler will do the work of adjusting the following offsets for you.
|
relative offsets, the assembler will do the work of adjusting the
|
||||||
|
following offsets for you.
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
.global main
|
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
|
|
||||||
main:
|
|
||||||
str x30, [sp, 16]!
|
|
||||||
|
|
||||||
ldr x0, =fmt
|
|
||||||
ldr x1, =Fee
|
|
||||||
ldr x2, [x1]
|
|
||||||
ldrh w3, [x1, 8]
|
|
||||||
ldr w4, [x1, 12]
|
|
||||||
bl printf
|
|
||||||
|
|
||||||
ldr x30, [sp], 16
|
|
||||||
mov w0, wzr
|
|
||||||
ret
|
|
||||||
|
|
||||||
.data
|
|
||||||
|
|
||||||
fmt: .asciz "%p a: 0x%lx b: %x c: %x\n"
|
|
||||||
15
section_1/structs/test02.s
Normal file
15
section_1/structs/test02.s
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
.arch armv8-a
|
||||||
|
.file "test02.c"
|
||||||
|
.text
|
||||||
|
.global Bar
|
||||||
|
.data
|
||||||
|
.align 3
|
||||||
|
.type Bar, %object
|
||||||
|
.size Bar, 8
|
||||||
|
Bar:
|
||||||
|
.hword -21846
|
||||||
|
.byte -69
|
||||||
|
.zero 1
|
||||||
|
.word -858993460
|
||||||
|
.ident "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
|
|
@ -1,21 +1,36 @@
|
||||||
.global main
|
#include "apple-linux-convergence.S"
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
|
|
||||||
main:
|
GLABEL main
|
||||||
str x30, [sp, 16]!
|
.text
|
||||||
|
.p2align 2
|
||||||
|
|
||||||
ldr x0, =fmt
|
MAIN
|
||||||
ldr x1, =Bar
|
PUSH_P x29, x30
|
||||||
ldrh w2, [x1]
|
mov x29, sp
|
||||||
ldrb w3, [x1, 2]
|
|
||||||
ldr w4, [x1, 4]
|
|
||||||
bl printf
|
|
||||||
|
|
||||||
ldr x30, [sp], 16
|
LLD_ADDR x0, fmt
|
||||||
mov w0, wzr
|
LLD_ADDR x1, bar
|
||||||
ret
|
ldrh w2, [x1, 0]
|
||||||
|
ldrb w3, [x1, 2]
|
||||||
|
ldr w4, [x1, 4]
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
PUSH_P x3, x4
|
||||||
|
PUSH_P x1, x2
|
||||||
|
CRT printf
|
||||||
|
add sp, sp, 32
|
||||||
|
#else
|
||||||
|
CRT printf
|
||||||
|
#endif
|
||||||
|
POP_P x29, x30
|
||||||
|
mov w0, wzr
|
||||||
|
ret
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n"
|
fmt: .asciz "%p a: 0x%lx b: %x c: %x\n"
|
||||||
|
bar: .short 0xaaaa
|
||||||
|
.byte 0xbb
|
||||||
|
.byte 0 // padding
|
||||||
|
.word 0xcccccccc
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,40 @@
|
||||||
.global main
|
#include "apple-linux-convergence.S"
|
||||||
|
|
||||||
|
GLABEL main
|
||||||
.text
|
.text
|
||||||
.align 2
|
.p2align 2
|
||||||
|
|
||||||
.equ foo_a, 0 # like #define
|
.equ foo_a, 0 // like #define
|
||||||
.equ foo_b, 2 # like #define
|
.equ foo_b, 2 // like #define
|
||||||
.equ foo_c, 4 # like #define
|
.equ foo_c, 4 // like #define
|
||||||
|
|
||||||
main:
|
MAIN
|
||||||
str x30, [sp, 16]!
|
PUSH_P x29, x30
|
||||||
|
mov x29, sp
|
||||||
|
|
||||||
ldr x0, =fmt
|
LLD_ADDR x0, fmt
|
||||||
ldr x1, =Bar
|
LLD_ADDR x1, bar
|
||||||
ldrh w2, [x1, foo_a]
|
ldrh w2, [x1, foo_a]
|
||||||
ldrb w3, [x1, foo_b]
|
ldrb w3, [x1, foo_b]
|
||||||
ldr w4, [x1, foo_c]
|
ldr w4, [x1, foo_c]
|
||||||
bl printf
|
#if defined(__APPLE__)
|
||||||
|
PUSH_P x3, x4
|
||||||
ldr x30, [sp], 16
|
PUSH_P x1, x2
|
||||||
|
CRT printf
|
||||||
|
add sp, sp, 32
|
||||||
|
#else
|
||||||
|
CRT printf
|
||||||
|
#endif
|
||||||
|
POP_P x29, x30
|
||||||
mov w0, wzr
|
mov w0, wzr
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n"
|
fmt: .asciz "%p a: 0x%lx b: %x c: %x\n"
|
||||||
|
bar: .short 0xaaaa
|
||||||
|
.byte 0xbb
|
||||||
|
.byte 0 // padding
|
||||||
|
.word 0xcccccccc
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,44 @@
|
||||||
.global main
|
#include "apple-linux-convergence.S"
|
||||||
|
|
||||||
|
// STRUCT DEFINITION WORKS ONLY FOR LINUX
|
||||||
|
|
||||||
|
GLABEL main
|
||||||
.text
|
.text
|
||||||
.align 2
|
.p2align 2
|
||||||
|
|
||||||
main:
|
MAIN
|
||||||
str x30, [sp, 16]!
|
PUSH_P x29, x30
|
||||||
|
mov x29, sp
|
||||||
|
|
||||||
ldr x0, =fmt
|
LLD_ADDR x0, fmt
|
||||||
ldr x1, =Bar
|
LLD_ADDR x1, bar
|
||||||
ldrh w2, [x1, Foo.a]
|
ldrh w2, [x1, Foo.a]
|
||||||
ldrb w3, [x1, Foo.b]
|
ldrb w3, [x1, Foo.b]
|
||||||
ldr w4, [x1, Foo.c]
|
ldr w4, [x1, Foo.c]
|
||||||
bl printf
|
#if defined(__APPLE__)
|
||||||
|
PUSH_P x3, x4
|
||||||
ldr x30, [sp], 16
|
PUSH_P x1, x2
|
||||||
|
CRT printf
|
||||||
|
add sp, sp, 32
|
||||||
|
#else
|
||||||
|
CRT printf
|
||||||
|
#endif
|
||||||
|
POP_P x29, x30
|
||||||
mov w0, wzr
|
mov w0, wzr
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.section Foo
|
.section Foo
|
||||||
.struct 0 // a starts at 0 and goes for 2
|
.struct 0 // a starts at 0 and goes for 2
|
||||||
Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2
|
Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2
|
||||||
Foo.b: .struct Foo.b + 2 // c starts at 4
|
Foo.b: .struct Foo.b + 2 // c starts at 4
|
||||||
Foo.c:
|
Foo.c:
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n"
|
fmt: .asciz "%p a: 0x%lx b: %x c: %x\n"
|
||||||
|
bar: .short 0xaaaa
|
||||||
|
.byte 0xbb
|
||||||
|
.byte 0 // padding
|
||||||
|
.word 0xcccccccc
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue