mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-21 01:56:47 +08:00
added new chapter on str len
This commit is contained in:
parent
4665bbe23e
commit
93ac3526d5
4 changed files with 110 additions and 1 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -24,6 +24,7 @@
|
|||
"simm",
|
||||
"smaddl",
|
||||
"stringstream",
|
||||
"strlen",
|
||||
"strncpy",
|
||||
"struct",
|
||||
"structs"
|
||||
|
|
@ -39,6 +40,8 @@
|
|||
"ndless",
|
||||
"ndmore",
|
||||
"rotypo",
|
||||
"rwtypo"
|
||||
"rwtypo",
|
||||
"slen",
|
||||
"ssize"
|
||||
]
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
74
more/strlen_for_c/README.md
Normal file
74
more/strlen_for_c/README.md
Normal file
|
|
@ -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
|
||||
```
|
||||
28
more/strlen_for_c/str_length.s
Normal file
28
more/strlen_for_c/str_length.s
Normal file
|
|
@ -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
|
||||
Loading…
Reference in a new issue