Skip to content
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

stack/intro: Lab 8 - Stiva #22

Open
wants to merge 1 commit into
base: main
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
13 changes: 13 additions & 0 deletions chapters/stack/intro/drills/tasks/gcd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# GCD - Greatest Common Divisor

Open `gcd.asm` and run the program.
The code calculates the greatest common divisor (GCD) of two numbers given as parameters using the `eax` and `edx` registers, and then stores the calculated value back in the `eax` register.

1. Make the necessary modifications so that the error message - `Segmentation fault (core dumped)` - no longer appears.
1. Within the `print` label, display the result in the following format:

```c
gcd(49,28)=7
```

If you're having difficulties solving this exercise, go through [this](../../../reading/README.md) reading material
1 change: 1 addition & 0 deletions chapters/stack/intro/drills/tasks/gcd/solution/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gcd
1 change: 1 addition & 0 deletions chapters/stack/intro/drills/tasks/gcd/solution/Makefile
45 changes: 45 additions & 0 deletions chapters/stack/intro/drills/tasks/gcd/solution/gcd.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
; SPDX-License-Identifier: BSD-3-Clause

%include "../utils/printf32.asm"
george-cosma marked this conversation as resolved.
Show resolved Hide resolved

section .text

extern printf
global main
main:
; Input values (eax, edx) : the 2 numbers to compute the gcd for.
mov eax, 49
mov edx, 28

push eax
push edx

gcd:
neg eax
je gcd_end

swap_values:
neg eax
push eax
push edx
pop eax
pop edx

subtract_values:
sub eax,edx
jg subtract_values
jne swap_values

gcd_end:
add eax,edx
jne print
inc eax

print:
pop edx
pop ebx

PRINTF32 `gcd(%d, %d) = %d\n\x0`, ebx, edx, eax ; eax = greatest common divisor

xor eax, eax
ret
1 change: 1 addition & 0 deletions chapters/stack/intro/drills/tasks/gcd/support/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gcd
25 changes: 25 additions & 0 deletions chapters/stack/intro/drills/tasks/gcd/support/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
AS = nasm
CC = gcc
RM = rm

SRCS := $(shell find . -name "*.asm")
OBJS := $(SRCS:.asm=.o)

UTILSDIR := ../utils/

ASFLAGS ?= -f elf32 -F dwarf -I "$(UTILSDIR)"
CFLAGS ?= -Wall
LDFLAGS ?= -m32 -no-pie

TARGET_EXEC = gcd

$(TARGET_EXEC): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@

$(OBJS): $(SRCS)
$(AS) $(ASFLAGS) $< -o $@

.PHONY: clean

clean:
$(RM) -r *.o $(TARGET_EXEC)
44 changes: 44 additions & 0 deletions chapters/stack/intro/drills/tasks/gcd/support/gcd.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
%include "printf32.asm"

section .text

extern printf
global main
main:
; input values (eax, edx): the 2 numbers to compute the gcd for
mov eax, 49
mov edx, 28

push eax
push edx

gcd:
neg eax
je gcd_end

swap_values:
neg eax
push eax
push edx
pop eax
pop edx

subtract_values:
sub eax,edx
jg subtract_values
jne swap_values

gcd_end:
add eax,edx
jne print
inc eax

print:

; TODO 1: solve the 'Segmentation fault!' error

; TODO 2: print the result in the form of: "gdc(eax, edx)=7" with PRINTF32 macro
; output value in eax

xor eax, eax
ret
24 changes: 24 additions & 0 deletions chapters/stack/intro/drills/tasks/gcd/utils/printf32.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
; SPDX-License-Identifier: BSD-3-Clause

;;; macro to use printf with 32bit parameters:
;;; - 1st parameter MUST be an immediate in backquotes `EAX=%d ECX=%x \n\x0`
;;; escape \n and \x0 only work with backquotes
;;; - rest of parameters MUST be 32bit
;;; - gen purpose and flags are preserved
;;; - stack is cleaned
%macro PRINTF32 1-*
pushf
pushad
jmp %%endstr
%%str: db %1
%%endstr:
%rep %0 - 1
%rotate -1
push dword %1
%endrep
push %%str
call printf
add esp, 4*%0
popad
popf
%endmacro
9 changes: 9 additions & 0 deletions chapters/stack/intro/drills/tasks/local-var/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Local Var

The program `local-var.asm` in the laboratory archive combines two sorted arrays (`array_1` and `array_2`) by placing the resulting array in `array_output` defined in the `.data` section.

Modify the program so that `array_1`, `array_2`, and `array_output` are allocated on the stack.
The array allocation is done using the `sub` instruction.
For the copies of arrays `array_1` and `array_2`, you will need to copy their elements from the `.data` section to the stack before using them.
george-cosma marked this conversation as resolved.
Show resolved Hide resolved

If you're having difficulties solving this exercise, go through [this](../../../reading/README.md) reading material
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
local-var
106 changes: 106 additions & 0 deletions chapters/stack/intro/drills/tasks/local-var/solution/local-var.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
%include "../utils/printf32.asm"

section .data

%define ARRAY_1_LEN 5
%define ARRAY_2_LEN 7
%define ARRAY_OUTPUT_LEN 12

section .data
array_1 dd 27, 46, 55, 83, 84
array_2 dd 1, 4, 21, 26, 59, 92, 105

section .text

extern printf
global main

main:
mov ebp, esp
sub esp, 4 * ARRAY_1_LEN
mov eax, esp
mov edx, 0
array_1_on_stack:
mov ecx, [array_1 + 4 * edx]
mov [eax], ecx
inc edx
add eax, 4
cmp edx, ARRAY_1_LEN
jl array_1_on_stack
mov eax, esp

sub esp, 4 * ARRAY_2_LEN
mov ebx, esp
mov edx, 0
array_2_on_stack:
mov ecx, [array_2 + 4 * edx]
mov [ebx], ecx
inc edx
add ebx, 4
cmp edx, ARRAY_2_LEN
jl array_2_on_stack
mov ebx, esp
sub esp, 4 * ARRAY_OUTPUT_LEN
mov ecx, esp

merge_arrays:
mov edx, [eax]
cmp edx, [ebx]
jg array_2_lower
array_1_lower:
mov [ecx], edx ; The element from array_1 is lower
add eax, 4
add ecx, 4
jmp verify_array_end
array_2_lower:
mov edx, [ebx]
mov [ecx], edx ; The elements of the array_2 is lower
add ebx, 4
add ecx, 4

verify_array_end:
mov edx, ebp
cmp eax, edx
jge copy_array_2
sub edx, 4 * ARRAY_1_LEN
cmp ebx, ebp
jge copy_array_1
jmp merge_arrays

copy_array_1:
xor edx, edx
mov eax, [eax]
mov [ecx], edx
add ecx, 4
add eax, 4
cmp eax, ebp
jb copy_array_1
jmp print_array
copy_array_2:
xor edx, edx
mov edx, [ebx]
mov [ecx], edx
add ecx, 4
add ebx, 4
mov edx, ebp
sub edx, 4 * ARRAY_1_LEN
cmp ebx, edx
jb copy_array_2

print_array:
PRINTF32 `Array merged:\n\x0`
xor eax, eax
xor ecx, ecx

print:
mov eax, [esp]
PRINTF32 `%d \x0`, eax
add esp, 4
inc ecx
cmp ecx, ARRAY_OUTPUT_LEN
jb print

PRINTF32 `\n\x0`
xor eax, eax
mov esp, ebp
ret
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
local-var
25 changes: 25 additions & 0 deletions chapters/stack/intro/drills/tasks/local-var/support/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
AS = nasm
CC = gcc
RM = rm

SRCS := $(shell find . -name "*.asm")
OBJS := $(SRCS:.asm=.o)

UTILSDIR := ../utils/

ASFLAGS ?= -f elf32 -F dwarf -I "$(UTILSDIR)"
CFLAGS ?= -Wall
LDFLAGS ?= -m32 -no-pie

TARGET_EXEC = local-var

$(TARGET_EXEC): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@

$(OBJS): $(SRCS)
$(AS) $(ASFLAGS) $< -o $@

.PHONY: clean

clean:
$(RM) -r *.o $(TARGET_EXEC)
73 changes: 73 additions & 0 deletions chapters/stack/intro/drills/tasks/local-var/support/local-var.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
%include "printf32.asm"

%define ARRAY_1_LEN 5
%define ARRAY_2_LEN 7
%define ARRAY_OUTPUT_LEN 12

section .data

array_1 dd 27, 46, 55, 83, 84
array_2 dd 1, 4, 21, 26, 59, 92, 105
array_output times 12 dd 0


section .text

extern printf
global main
main:
mov eax, 0 ; counter used for array_1
mov ebx, 0 ; counter used for array_2
mov ecx, 0 ; counter used for the output array

merge_arrays:
mov edx, [array_1 + 4 * eax]
cmp edx, [array_2 + 4 * ebx]
jg array_2_lower
array_1_lower:
mov [array_output + 4 * ecx], edx
inc eax
inc ecx
jmp verify_array_end
array_2_lower:
mov edx, [array_2 + 4 * ebx]
mov [array_output + 4 * ecx], edx
inc ecx
inc ebx

verify_array_end:
cmp eax, ARRAY_1_LEN
jge copy_array_2
cmp ebx, ARRAY_2_LEN
jge copy_array_1
jmp merge_arrays

copy_array_1:
mov edx, [array_1 + 4 * eax]
mov [array_output + 4 * ecx], edx
inc ecx
inc eax
cmp eax, ARRAY_1_LEN
jb copy_array_1
jmp print_array
copy_array_2:
mov edx, [array_2 + 4 * ebx]
mov [array_output + 4 * ecx], edx
inc ecx
inc ebx
cmp ebx, ARRAY_2_LEN
jb copy_array_2

print_array:
PRINTF32 `Array merged:\n\x0`
mov ecx, 0
print:
mov eax, [array_output + 4 * ecx]
PRINTF32 `%d \x0`, eax
inc ecx
cmp ecx, ARRAY_OUTPUT_LEN
jb print

PRINTF32 `\n\x0`
xor eax, eax
ret
Loading
Loading