1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
title: ARM64 process command line arguments in assembly
keywords:raspi5,asm,c,kernel,arm64
# ARM64 process command line arguments in assembly
## Intro
Goal is to learn how to get command line arguments in assembly
and do basic processing for Linux kernel, all is tested with Raspberry Pi4 on 64bit OS.
## Location of arguments
Operating system provides number of arguments, command line arguments and
environment variables. Pointers for those located in stack and location
of actual values also reference in allocated stack from operating system.
## Checking for argument number
Number of arguments passed to command line utility is located
at stack pointers first value. Argument number located at
_sp_ address, after that there is arguments here we check number
of arguments if there is less then 1, it always more then 1 as
first argument is always program calling path
```c
ldr x3, [sp]
cmp x3, #1
b.LE exit_program
```
## Printing out all arguments
Pointers to the argument values are after the stack pointers first value.
As first value in stack pointer is number of arguments passed then need to
ensure to not go over it.
### Write strlen function
There is no default strlen instruction in assembly, so need to write
one our-self. I used _x0_ as input argument, _x1_ as internal counter
_w2_ to get and compare string char and _x1_ is where final amount
of characters is saved.
```c
//param 0: x0 pointer to string
//using registers: x2
//return result in x1:
strlen:
mov x1, #0 //number of arguments
loop_strlen_till_0:
//check if str[] element is 0
ldrb w2, [x0] //ldrb w2, [x2]
//if element of string is zero then exit
cbz w2, string_element_eq_zero
//if element isnt 0 then add +1 to counted size
add x1, x1, 1
//increase str pointer +1
add x0, x0, #1
b loop_strlen_till_0
string_element_eq_zero:
ret
```
### Printing out all arguments passed
Next step is to utilize strlen function and printout all arguments
passed from command line
```c
argument_print_loop:
//number of arguments now in x4
//get the value of the first argument
//add x0, sp, #8
mov x0, x4
ldr x0, [x0]
//x0 points to firt argument of programm name
bl strlen
//write
mov x2, x1
mov x0, #1 //set stdout
ldr x1, [x4] //point to programm name
//ldr x5, =program_len //hopefully correct size of print_arg
//ldr x2, [x5]
mov w8, #64
svc #0
//print new line
mov x0, #1 //set stdout
ldr x1, =new_line //point to newline
mov x2, #1
mov w8, #64
svc #0
add x4, x4, #8
sub x3, x3, 1
cmp x3, 1
b.GE argument_print_loop
```
All programm seems to work ok
## Source code
Final source code of this example
```c
.data
hello_world:
.ascii "print arg program\n"
hello_world_len = . - hello_world
new_line:
.ascii "\n"
program_len: .quad 11
.text
.global _start
_start:
//save to x0 number of arguments
ldr x3, [sp]
//save to x1 address of first argument
add x4, sp, #8
//write hello world
mov x0, #1
ldr x1, =hello_world
ldr x2, =hello_world_len
mov w8, #64
svc #0
argument_print_loop:
//number of arguments now in x4
//get the value of the first argument
mov x0, x4
ldr x0, [x0] //x0 points to firt argument of programm name
bl strlen
//write
mov x2, x1
mov x0, #1 //set stdout
ldr x1, [x4] //point to programm name
mov w8, #64
svc #0
//print new line
mov x0, #1 //set stdout
ldr x1, =new_line //point to newline
mov x2, #1
mov w8, #64
svc #0
add x4, x4, #8
sub x3, x3, 1
cmp x3, 1
b.GE argument_print_loop
exit_program:
//exit(0)
ldr x0, #0
mov w8, #93
svc #0
//param 0: x0 pointer to string
//using registers: x2
//return result in x1:
strlen:
mov x1, #0 //number of arguments
loop_strlen_till_0:
//check if str[] element is 0
ldrb w2, [x0] //ldrb w2, [x2]
//if element of string is zero then exit
cbz w2, string_element_eq_zero
//if element isnt 0 then add +1 to counted size
add x1, x1, 1
//increase str pointer +1
add x0, x0, #1
b loop_strlen_till_0
string_element_eq_zero:
ret
```
## Comilation size
|Program name |Uncompressed size|Compressed size|
|---|---|---|
|print_arg| 1552 bytes | 481 bytes |
## Links
[Make tiny binary](/writeup/arm64_make_tiny_binary.md)
|