From 93ac3526d5eea8b130d7b8267d8ffd5b2ca1110a Mon Sep 17 00:00:00 2001 From: Perry Kivolowitz Date: Sun, 7 Aug 2022 12:13:56 -0500 Subject: [PATCH] added new chapter on str len --- .vscode/settings.json | 5 ++- README.md | 4 ++ more/strlen_for_c/README.md | 74 ++++++++++++++++++++++++++++++++++ more/strlen_for_c/str_length.s | 28 +++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 more/strlen_for_c/README.md create mode 100644 more/strlen_for_c/str_length.s diff --git a/.vscode/settings.json b/.vscode/settings.json index b38cce6..01e9df0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,6 +24,7 @@ "simm", "smaddl", "stringstream", + "strlen", "strncpy", "struct", "structs" @@ -39,6 +40,8 @@ "ndless", "ndmore", "rotypo", - "rwtypo" + "rwtypo", + "slen", + "ssize" ] } \ No newline at end of file diff --git a/README.md b/README.md index 3da68b0..0f748cc 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,10 @@ the 64 bit ARM Instruction Set Architecture (ISA). ## Section 3 - More Stuff +| Chapter | Content | +| ------- | ------- | +| --- | [Determing string length for C functions](./more/strlen_for_c/README.md) | + ## Projects [Here](./projects/README.md) are some project specifications to offer a challenge to your growing mastery. diff --git a/more/strlen_for_c/README.md b/more/strlen_for_c/README.md new file mode 100644 index 0000000..12b513f --- /dev/null +++ b/more/strlen_for_c/README.md @@ -0,0 +1,74 @@ +# Determining the Length of Strings for C Functions + +C string have no soul, is something I like to tell my students. Unlike +C++ strings, you can't ask them to tell you how long they are. Instead +you must use another function such as `strlen()`. + +When a string is fixed within your assembly code, you can let the +assembler itself calculate the length for you. + +Here is an example of a C function that requires you to specify a +string's length: + +```c +write(1, "Hello, World!\n", 14); +``` + +This sends the familiar string to `stdout`. + +In assembly language, the string would have been placed in a `.data` +section using the `.asciz` directive. But! How to get the length of the +string? You could: + +* hard code the length as I did above, or + +* go through the effort of calling `strlen()` + +There is a third option as demonstrated by the +[following program](./str_length.s): + +```text + .global main // 1 + .align 2 // 2 + .text // 3 + // 4 +main: str x30, [sp, -16]! // 5 + mov w0, 1 // stdout // 6 + ldr x1, =s // pointer to string // 7 + ldr x2, =ssize // pointer to computed length // 8 + ldr w2, [x2] // actual length of string // 9 + bl write // 10 + // 11 + ldr x0, =fmt // 12 + ldr x1, =s // 13 + ldr x2, =ssize // 14 + ldr w2, [x2] // 15 + bl printf // 16 + // 17 + ldr x30, [sp], 16 // 18 + mov w0, wzr // 19 + ret // 20 + // 21 + .data // 22 + // 23 +s: .asciz "Hello, World!\n" // 24 +ssize: .word ssize - s - 1 // accounts for null at end // 25 +fmt: .asciz "str: %slen: %d\n" // accounts for newline // 26 + // 27 + .end // 28 +``` + +`Line 24` contains the string. It is null terminated. + +`Line 25` is the new learning. The assembler calculates the difference +between the address of `s` and the address of `ssize` and puts it at the +location of `ssize`. Then, it is used on `Lines 8` and `9` like any +other statically stored data. + +Here is the output of the program: + +```text +Hello, World! +str: Hello, World! +len: 14 +``` diff --git a/more/strlen_for_c/str_length.s b/more/strlen_for_c/str_length.s new file mode 100644 index 0000000..211095d --- /dev/null +++ b/more/strlen_for_c/str_length.s @@ -0,0 +1,28 @@ + .global main + .align 2 + .text + +main: str x30, [sp, -16]! + mov w0, 1 // stdout + ldr x1, =s // pointer to string + ldr x2, =ssize // pointer to computed length + ldr w2, [x2] // actual length of string + bl write + + ldr x0, =fmt + ldr x1, =s + ldr x2, =ssize + ldr w2, [x2] + bl printf + + ldr x30, [sp], 16 + mov w0, wzr + ret + + .data + +s: .asciz "Hello, World!\n" +ssize: .word ssize - s - 1 // accounts for null at end +fmt: .asciz "str: %slen: %d\n" // accounts for newline + + .end