Skip to content

asm-4: Rework of the 4th chapter #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ dkms.conf
hello/hello
sum/sum
stack/stack
strings/reverse
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Here are links to each post:
* [Part 1. Introduction](https://github.com/0xAX/asm/blob/master/content/asm_1.md)
* [Part 2. The `x86_64` concepts](https://github.com/0xAX/asm/blob/master/content/asm_2.md)
* [Part 3. Journey through the stack](https://github.com/0xAX/asm/blob/master/content/asm_3.md)
* [Say hello to x86_64 Assembly part 4](https://github.com/0xAX/asm/blob/master/content/asm_4.md)
* [Part 4. Data manipulation](https://github.com/0xAX/asm/blob/master/content/asm_4.md)
* [Say hello to x86_64 Assembly part 5](https://github.com/0xAX/asm/blob/master/content/asm_5.md)
* [Say hello to x86_64 Assembly part 6](https://github.com/0xAX/asm/blob/master/content/asm_6.md)
* [Say hello to x86_64 Assembly part 7](https://github.com/0xAX/asm/blob/master/content/asm_7.md)
Expand Down
375 changes: 246 additions & 129 deletions content/asm_4.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ glob_ignore_case = false
# Exclude URLs from checking (supports regex).
exclude = [
"https://www.gnu.org/software/emacs",
"https://www.gnu.org/software/make",
"https://www.gnu.org/software/binutils",
"https://makeapullrequest.com",
"https://x.com/0xAX"
]
Expand Down
12 changes: 8 additions & 4 deletions strings/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
This is "reverse string" with assembly for Linux x86-64.
# Reverse string

Build it with: `make`
This is a simple program that reverses a given input string with assembly for Linux x86-64.

More details at - [Say hello to x64 Assembly [part 4]](https://github.com/0xAX/asm/blob/master/content/asm_4.md)
To build the program, run:

[@0xAX](https://x.com/0xAX)
```bash
make
```

For more details, read [Part 4. Journey through the stack](https://github.com/0xAX/asm/blob/master/content/asm_4.md).
198 changes: 89 additions & 109 deletions strings/reverse.asm
Original file line number Diff line number Diff line change
@@ -1,123 +1,103 @@
;;
;; initialized data
;;
;; Definition of the .data section
section .data
SYS_WRITE equ 1
STD_OUT equ 1
SYS_EXIT equ 60
EXIT_CODE equ 0
;; Number of the `sys_write` system call.
SYS_WRITE equ 1
;; Number of the `sys_exit` system call.
SYS_EXIT equ 60
;; Number of the standard output file descriptor.
STD_OUT equ 1
;; Exit code from the program. The 0 status code is a success.
EXIT_CODE equ 0
;; Length of the string with only new line symbol.
NEW_LINE_LEN equ 1

NEW_LINE db 0xa
INPUT db "Hello world!"
;; ASCII code of the new line symbol ('\n').
NEW_LINE db 0xa
;; Input string that we are going to reverse
INPUT db "Hello world!"

;;
;; non initialized data
;;
;; Definition of the .bss section.
section .bss
OUTPUT resb 1
;; Output buffer where the reversed string will be stored.
OUTPUT resb 1

;;
;; code
;;
;; Definition of the .text section.
section .text
global _start
;; Reference to the entry point of our program.
global _start

;;
;; main routine
;;
;; Entry point of the program.
_start:
;; get addres of INPUT
mov rsi, INPUT
;; zeroize rcx for counter
xor rcx, rcx
; df = 0 si++
cld
; remember place after function call
mov rdi, $ + 15
;; get string lengt
call calculateStrLength
;; write zeros to rax
xor rax, rax
;; additional counter for reverseStr
xor rdi, rdi
;; reverse string
jmp reverseStr
;; Set rcx value to 0. It will be used as a storage for the input string length.
xor rcx, rcx
;; Store the address of the input string in the rsi register.
mov rsi, INPUT
;; Store the address of the output buffer in the rdi register.
mov rdi, OUTPUT
;; Clear direction flag. To handle string from left to right.
cld
;; Call the reverseStringAndPrint procedure.
call reverseStringAndPrint

;;
;; calculate length of string
;;
calculateStrLength:
;; check is it end of string
cmp byte [rsi], 0
;; if yes exit from function
je exitFromRoutine
;; load byte from rsi to al and inc rsi
lodsb
;; push symbol to stack
push rax
;; increase counter
inc rcx
;; loop again
jmp calculateStrLength
;; Calculate the length of the input string and prepare to reverse it.
reverseStringAndPrint:
;; Compare the first element in the given string with the NUL terminator (end of the string).
cmp byte [rsi], 0
;; If we reached the end of the input string, reverse it.
je reverseString
;; Load byte from the rsi to al register and move pointer to the next character in the string.
lodsb
;; Save the character of the input string on the stack.
push rax
;; Increase the counter that stores the length of our input string.
inc rcx
;; Continue to go over the input string if we did not reach end of if.
jmp reverseStringAndPrint

;;
;; back to _start
;;
exitFromRoutine:
;; push return addres to stack again
push rdi
;; return to _start
ret
;; Reverse the string and store it in the output buffer.
reverseString:
;; Check the counter that stores the length of the string.
cmp rcx, 0
;; If it is equal to `0`, print the reverse string.
je printResult
;; Pop the character from the stack.
pop rax
;; Put the character to the output buffer.
mov [rdi], rax
;; Move the pointer to the next character in the output buffer.
inc rdi
;; Decrease the counter of the length of the string.
dec rcx
;; Move to the next character while we did not reach the end of the string.
jmp reverseString

;;
;; reverse string
;;
;; 31 in stack
reverseStr:
;; check is it end of string
cmp rcx, 0
;; if yes print result string
je printResult
;; get symbol from stack
pop rax
;; write it to output buffer
mov [OUTPUT + rdi], rax
;; decrease length counter
dec rcx
;; increase additional length counter (for write syscall)
inc rdi
;; loop again
jmp reverseStr

;;
;; Print result string
;;
;; Print the reversed string to the standard output.
printResult:
mov rdx, rdi
mov rax, 1
mov rdi, 1
mov rsi, OUTPUT
syscall
jmp printNewLine
;; Set the the length of the result string to print.
mov rdx, rdi
;; Specify the system call number (1 is `sys_write`).
mov rax, SYS_WRITE
;; Set the first argument of `sys_write` to 1 (`stdout`).
mov rdi, STD_OUT
;; Set the second argument of `sys_write` to the reference of the result string to print.
mov rsi, OUTPUT
;; Call the `sys_write` system call.
syscall

;;
;; Print new line
;;
printNewLine:
mov rax, SYS_WRITE
mov rdi, STD_OUT
mov rsi, NEW_LINE
mov rdx, 1
syscall
jmp exit
;; Set the the length of the result string to print.
mov rdx, NEW_LINE_LEN
;; Specify the system call number (1 is `sys_write`).
mov rax, SYS_WRITE
;; Set the first argument of `sys_write` to 1 (`stdout`).
mov rdi, STD_OUT
;; Set the second argument of `sys_write` to the reference of the result string to print.
mov rsi, NEW_LINE
;; Call the `sys_write` system call.
syscall

;;
;; Exit from program
;;
exit:
;; syscall number
mov rax, SYS_EXIT
;; exit code
mov rdi, EXIT_CODE
;; call sys_exit
syscall
;; Specify the number of the system call (60 is `sys_exit`).
mov rax, SYS_EXIT
;; Set the first argument of `sys_exit` to 0. The 0 status code is a success.
mov rdi, EXIT_CODE
;; Call the `sys_exit` system call.
syscall
Loading