diff --git a/labs/lab-09/reading/calling-convention.md b/labs/lab-09/reading/calling-convention.md index fafa9bab7..31d57fd85 100644 --- a/labs/lab-09/reading/calling-convention.md +++ b/labs/lab-09/reading/calling-convention.md @@ -49,10 +49,10 @@ main: mov rdi, fmt mov rsi, text + xor rax, rax call printf pop rbp - xor rax, rax ret ``` diff --git a/labs/lab-09/reading/memory-layout-c-asm.md b/labs/lab-09/reading/memory-layout-c-asm.md index 82f45645c..a8b3c4c8f 100644 --- a/labs/lab-09/reading/memory-layout-c-asm.md +++ b/labs/lab-09/reading/memory-layout-c-asm.md @@ -40,14 +40,20 @@ section .data text db "291 is the best!", 10, 0 strformat db "%s", 0 -section .code +section .text +global main main: - push dword text - push dword strformat - call printf - add esp, 8 - ret + push rbp + mov rbp, rsp + + mov rdi, strformat + mov rsi, text + xor rax, rax + call printf + + leave + ret ``` Note that the procedure is declared as global and is called `main` - the starting point of any C program. diff --git a/labs/lab-09/tasks/max-assembly-calls/solution/main.asm b/labs/lab-09/tasks/max-assembly-calls/solution/main.asm index ea28cd6b2..707810978 100644 --- a/labs/lab-09/tasks/max-assembly-calls/solution/main.asm +++ b/labs/lab-09/tasks/max-assembly-calls/solution/main.asm @@ -37,6 +37,7 @@ main: mov rdi, fmt mov rsi, rax mov edx, dword [pos] + xor rax, rax call printf ; set exit code 0 (in main) diff --git a/labs/lab-09/tasks/max-assembly-calls/support/main.asm b/labs/lab-09/tasks/max-assembly-calls/support/main.asm index d5228f675..707810978 100644 --- a/labs/lab-09/tasks/max-assembly-calls/support/main.asm +++ b/labs/lab-09/tasks/max-assembly-calls/support/main.asm @@ -7,7 +7,12 @@ section .data arr: dd 19, 7, 129, 87, 54, 218, 67, 12, 19, 99 len: equ $-arr - fmt: db "max: %u", 10, 0 + fmt: db "max: %u on position: %u", 10, 0 + +section .bss + ; we are _reserving_ space for a double word (4 bytes) + ; but we are not initializing it; so it can't reside in .data + pos: resd 1 section .text @@ -23,12 +28,16 @@ main: shr rsi, 2 mov rdi, arr + mov rdx, pos call get_max - ; print maximum value + ; print maximum value and its position ; NOTE: RAX holds the return value of get_max() + ; NOTE: pos written by get_max() at given memory address mov rdi, fmt mov rsi, rax + mov edx, dword [pos] + xor rax, rax call printf ; set exit code 0 (in main) diff --git a/labs/lab-09/tasks/max-c-calls-x86/solution/max.asm b/labs/lab-09/tasks/max-c-calls-x86/solution/max.asm index b0a4fce24..b40eda8b7 100644 --- a/labs/lab-09/tasks/max-c-calls-x86/solution/max.asm +++ b/labs/lab-09/tasks/max-c-calls-x86/solution/max.asm @@ -5,33 +5,46 @@ section .text global get_max -; RDI = array pointer -; RSI = array length -; RDX = pos pointer +; EDI = array pointer +; ESI = array length +; EDX = pos pointer get_max: - push rbp - mov rbp, rsp + push ebp + mov ebp, esp + + ; save registers + push edi + push esi + + mov edi, [ebp + 8] + mov esi, [ebp + 12] + mov edx, [ebp + 16] + ; initialize EAX with the first value as currently known maximum - mov eax, [rdi] - mov [rdx], eax + mov eax, [edi] + mov dword [edx], 0 - ; initialize RCX as loop counter for remaining elements - mov rcx, rsi - dec rcx + ; initialize ECX as loop counter for remaining elements + mov ecx, esi + dec ecx ; loop over remaining array elements compare: - cmp eax, [rdi + 4*rcx] - jge check_end + cmp eax, [edi + 4*ecx] + jae check_end ; update maximum and its position - mov eax, [rdi + 4*rcx] - mov [rdx], ecx + mov eax, [edi + 4*ecx] + mov [edx], ecx check_end: loop compare - ; result stored in RAX + ; result stored in EAX + + ; restore registers + pop esi + pop edi leave ret diff --git a/labs/lab-09/tasks/max-c-calls-x86/support/max.asm b/labs/lab-09/tasks/max-c-calls-x86/support/max.asm index 1794c71ba..a577d66de 100644 --- a/labs/lab-09/tasks/max-c-calls-x86/support/max.asm +++ b/labs/lab-09/tasks/max-c-calls-x86/support/max.asm @@ -5,29 +5,36 @@ section .text global get_max -; RDI = array pointer -; RSI = array length +; EDI = array pointer +; ESI = array length get_max: - push rbp - mov rbp, rsp + push ebp + mov ebp, esp + + ; save registers + push edi + push esi + + mov edi, [ebp + 8] + mov esi, [ebp + 12] ; initialize EAX with the first value as currently known maximum - mov eax, [rdi] + mov eax, [edi] - ; initialize RCX as loop counter for remaining elements - mov rcx, rsi - dec rcx + ; initialize ECX as loop counter for remaining elements + mov ecx, esi + dec ecx - ; loop over remaining array elements compare: - cmp eax, [rdi + 4*rcx] - jge check_end - mov eax, [rdi + 4*rcx] + cmp eax, [edi + 4*ecx] + jae check_end + mov eax, [edi + 4*ecx] check_end: loop compare - ; result stored in RAX + ; restore registers + pop esi + pop edi leave ret - diff --git a/labs/lab-09/tasks/regs-preserve/solution/main.asm b/labs/lab-09/tasks/regs-preserve/solution/main.asm index be5df9353..83c18dd9b 100644 --- a/labs/lab-09/tasks/regs-preserve/solution/main.asm +++ b/labs/lab-09/tasks/regs-preserve/solution/main.asm @@ -44,12 +44,12 @@ next: mov rdi, newline call printf - ; restore preserved register - pop rbx - ; restore the stack after calling printf add rsp, 8 + ; restore preserved register + pop rbx + leave ret diff --git a/labs/lab-09/tasks/regs-preserve/support/main.asm b/labs/lab-09/tasks/regs-preserve/support/main.asm index 1f5b8cfe8..a79f17199 100644 --- a/labs/lab-09/tasks/regs-preserve/support/main.asm +++ b/labs/lab-09/tasks/regs-preserve/support/main.asm @@ -27,7 +27,8 @@ print_reverse_array: mov rcx, rsi next: - ; TODO1: uncomment the following two lines + ; TODO1: uncomment push rcx and pop rcx. + ; Note: pushing rcx also aligns the stack to 16 bytes for printf. ; push rcx xor rax, rax mov esi, [rbx + 4*rcx - 4] @@ -40,6 +41,7 @@ next: mov rdi, newline call printf + ; restore preserved register pop rbx diff --git a/labs/lab-09/tasks/regs-preserve/tests/results.txt b/labs/lab-09/tasks/regs-preserve/tests/results.txt new file mode 100644 index 000000000..e69de29bb