Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,6 @@ sum/sum
stack/stack
strings/reverse
float/dot_product
casm/casm1/casm
casm/casm2/casm
casm/casm3/casm
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Here are links to each post:
* [Part 4. Data manipulation](https://github.com/0xAX/asm/blob/master/content/asm_4.md)
* [Part 5. Macros](https://github.com/0xAX/asm/blob/master/content/asm_5.md)
* [Part 6. Floating-point arithmetic](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)
* [Part 7. Interaction of assembly and high-level programming languages](https://github.com/0xAX/asm/blob/master/content/asm_7.md)

## Requirements

Expand Down
15 changes: 15 additions & 0 deletions casm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Assembly interaction with high-level programming languages

These are three simple programs which provides examples of interaction of assembly and C programming languages:

- casm1 - call C function from asm
- casm2 - gcc inline assembly
- casm3 - call asm function from C

To build each program, go to the directory with it and run:

```bash
make
```

For more details, read [Part 7. Interaction of assembly and high-level programming languages](https://github.com/0xAX/asm/blob/master/content/asm_7.md).
11 changes: 0 additions & 11 deletions casm/Readme.md

This file was deleted.

5 changes: 2 additions & 3 deletions casm/casm1/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
buildAsmc:
gcc -c casm.c -o c.o
all:
nasm -f elf64 casm.asm -o casm.o
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc casm.o c.o -o casm
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc casm.o -o casm

clean:
rm -rf *.o
Expand Down
28 changes: 22 additions & 6 deletions casm/casm1/casm.asm
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
global _start
;; Definition of the `data` section
section .data
;; String `msg` variable with the value `hello world!`
msg db "hello, world!"

extern print
;; Reference to the C stdlib functions that we will use
extern write, exit

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

;; Entry point
_start:
call print
;; Set the first argument of `write` function to 1 (`stdout`).
mov rdi, 1
;; Set the second argument of `write` function to the reference of the `msg` variable.
mov rsi, msg
;; Set the third argument to the length of the `msg` variable's value (13 bytes).
mov rdx, 13
;; Call the `write` function.
call write

mov rax, 60
mov rdi, 0
syscall
;; Set the first argument of `sys_exit` to 0. The 0 status code is success.
mov rdi, 0
;; Call the `exit` function
call exit
8 changes: 0 additions & 8 deletions casm/casm1/casm.c

This file was deleted.

8 changes: 6 additions & 2 deletions casm/casm2/Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
build:
gcc casm.c -o casm
all:
gcc casm.c -o casm

clean:
rm -rf *.o
rm -rf casm
16 changes: 9 additions & 7 deletions casm/casm2/casm.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
#include <stdio.h>
#include <string.h>

int main() {
char* str = "Hello World\n";
long len = strlen(str);
int ret = 0;

__asm__("movq $1, %%rax \n\t"
"movq $1, %%rdi \n\t"
"movq %1, %%rsi \n\t"
"movl %2, %%edx \n\t"
"syscall"
: "=g"(ret)
: "g"(str), "g" (len));
__asm__("movq $1, %%rax \n\t" // rax = 1 - Specify the number of the system call (1 is `sys_write`).
"movq $1, %%rdi \n\t" // rdi = 1 - Set the first argument of `sys_write` to 1 (`stdout`).
"movq %1, %%rsi \n\t" // rsi = str - Set the second argument of `sys_write` to the reference of the `str` variable.
"movq %2, %%rdx \n\t" // rdx = len(str) - Set the third argument of `sys_write` to the length of the `str` variable's value.
"syscall" // Call the `sys_write` system call.
: "=g"(ret) // Return the result in the `ret` variable.
: "g"(str), "g" (len)); // Put `str` and `len` variables in any general operand (memory, register or immediate if possible)

printf("Bytes written: %d\n", ret);
return 0;
}
6 changes: 5 additions & 1 deletion casm/casm3/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
build:
all:
nasm -f elf64 -o casm.o casm.asm
gcc casm.o casm.c -o casm

clean:
rm -rf *.o
rm -rf casm
35 changes: 21 additions & 14 deletions casm/casm3/casm.asm
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
global printHelloWorld

;; Definition of the text section
section .text
printHelloWorld:
;; 1 arg
mov r10, rdi
;; 2 arg
mov r11, rsi
;; call write syscall
mov rax, 1
mov rdi, 1
mov rsi, r10
mov rdx, r11
syscall
ret
;; Reference to the entry point of our program
global my_strlen

;; Function that returns the length of the string passed via the first argument
my_strlen:
;; Reset the register value to zero. It will be returned from the
;; function with the result.
xor rax, rax
.loop:
;; Compare the first element in the given string with the `NUL` terminator (end of the string).
cmp byte [rdi + rax], 0
;; If we reached the `NUL` terminator exit from the function.
je .done
;; Increase the counter which stores the length of the string.
inc rax
;; Repeat the operations above while we didn't reach the end of the string.
jmp .loop
.done:
;; Exit from the function and return the result in the `rax` register.
ret
19 changes: 12 additions & 7 deletions casm/casm3/casm.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

extern void printHelloWorld(char *str, int len);
extern int my_strlen(const char *str);

int main() {
char* str = "Hello World\n";
int len = strlen(str);
printHelloWorld(str, len);
return 0;
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Error: this program must have 1 command line argument\n");
return EXIT_FAILURE;
}

printf("The argument length is - %d\n", my_strlen(argv[1]));

return 0;
}
6 changes: 3 additions & 3 deletions content/asm_1.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ In addition to a Linux machine, you’ll need compilers to build the examples we
- [NASM](https://nasm.us/)
- [GNU LD](https://sourceware.org/binutils/docs/ld/)

We will use these three tools in most of the examples. If we need additional tools, I’ll mention them in the relevant example descriptions. You can install GNU GCC, NASM, and GNU LD using your Linux distribution’s package manager. For [Debian](https://www.debian.org/) or [Ubuntu](https://ubuntu.com/)-based distributions, use:
We will use these three tools in most of the examples. If we need additional tools, I’ll mention them in the relevant example descriptions. You can install GNU GCC, NASM, and GNU LD using your Linux distribution’s package manager. For [Debian](https://www.debian.org/)-based distributions, use:

```bash
sudo apt-get install gcc nasm binutils
Expand Down Expand Up @@ -158,11 +158,11 @@ _start:
mov rdi, 1
;; Set the second argument of `sys_write` to the reference of the `msg` variable.
mov rsi, msg
;; Set the third argument to the length of the `msg` variable's value (13 bytes).
;; Set the third argument of `sys_write` to the length of the `msg` variable's value (13 bytes).
mov rdx, 13

;; Call the `sys_write` system call.
syscall

;; Specify the number of the system call (60 is `sys_exit`).
mov rax, 60
;; Set the first argument of `sys_exit` to 0. The 0 status code is success.
Expand Down
4 changes: 2 additions & 2 deletions content/asm_3.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ str_to_int:
;; Base for multiplication
mov rcx, 10
__repeat:
;; Compare the first element in the given string with the NUL terminator (end of the string).
;; Compare the first element in the given string with the `NUL` terminator (end of the string).
cmp [rsi], byte 0
;; If we reached the end of the string, return from the procedure. The result is stored in the rax register.
je __return
Expand Down Expand Up @@ -435,7 +435,7 @@ str_to_int:
;; Base for multiplication
mov rcx, 10
__repeat:
;; Compare the first element in the given string with the NUL terminator (end of the string).
;; Compare the first element in the given string with the `NUL` terminator (end of the string).
cmp [rsi], byte 0
;; If we reached the end of the string, return from the procedure. The result is stored in the rax register.
je __return
Expand Down
2 changes: 1 addition & 1 deletion content/asm_4.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ After that, we need to call the `reverseStringAndPrint` procedure to calculate t
```assembly
;; 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).
;; Compare the first element in the given string with the `NUL` terminator (end of the string).
cmp byte [rsi], 0
;; Preserve the length of the reversed string in the rdx register. We will use this value when printing the string.
mov rdx, rcx
Expand Down
Loading