summaryrefslogtreecommitdiff
path: root/md/writeup
diff options
context:
space:
mode:
authorArturs Artamonovs <dos21h@gmail.com>2025-10-04 23:46:00 +0100
committerArturs Artamonovs <dos21h@gmail.com>2025-10-04 23:46:00 +0100
commit600f4e5409e257d0e26fe2b22951ea78d8323af5 (patch)
tree66538d5ec8dd278ef59c35f43aa41990f092bc7d /md/writeup
parentc706eb91161ed2077f85ad2a771d0f4c69ef09c1 (diff)
downloadmd-content-600f4e5409e257d0e26fe2b22951ea78d8323af5.tar.gz
md-content-600f4e5409e257d0e26fe2b22951ea78d8323af5.zip
add assembly command line argument parsingHEADmaster
Diffstat (limited to 'md/writeup')
-rw-r--r--md/writeup/arm64_assembly_command_line_arguments.md199
1 files changed, 199 insertions, 0 deletions
diff --git a/md/writeup/arm64_assembly_command_line_arguments.md b/md/writeup/arm64_assembly_command_line_arguments.md
new file mode 100644
index 0000000..7b18375
--- /dev/null
+++ b/md/writeup/arm64_assembly_command_line_arguments.md
@@ -0,0 +1,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) \ No newline at end of file