I'm new to C and Assembly programming, and I want to implement merge sort algorithm in C. A section of my C code should call Assembly function which will perform the merge action and return a sorted array to my C program. I have been able to write my entire merge sort algorithm in C and wanted to convert merge action to Assembly code but I don't know how to write it. Most importantly, how to link my Assembly file (.asm) to my C file (.c) so that when I run my C program it will execute the Assembly code.
My C code with Merge sort algorithm:
#include <stdio.h>
extern int * merge(int *left, int *right, unsigned long nLeft, unsigned long nRight, int *array);
//void merge(int const left[], int const right[], long nLeft, long nRight, int array[]) {
// int i = 0, j = 0, k = 0;
// while (i < nLeft && j < nRight) {
// if (left[i] <= right[j]) {
// array[k] = left[i];
// i++;
// } else {
// array[k] = right[j];
// j++;
// }
// k++;
// }
// while (i < nLeft) {
// array[k] = left[i];
// i++;
// k++;
// }
// while (j < nRight) {
// array[k] = right[j];
// j++;
// k++;
// }
//}
void printArray(int arr[], int size) {
for (int i = 0; i < size; ++i) {
printf("%d ", arr[i]);
}
}
void mergeSort(int arr[], unsigned long arrSize) {
if (arrSize < 2) {
return;
}
int* arrayPointer;
unsigned long mid = arrSize / 2;
int left[mid];
int right[arrSize - mid];
for (int i = 0; i < mid; i++)
left[i] = arr[i];
for (int i = (int) mid; i < arrSize; i++)
right[i - mid] = arr[i];
mergeSort(left, sizeof(left) / sizeof(int));
mergeSort(right, sizeof(right) / sizeof(int));
arrayPointer = merge(left, right, sizeof(left) / sizeof(int), sizeof(right) / sizeof(int), arr);
printf("Pointer %p\n", arrayPointer);
}
int main() {
int array[] = {3, 8, 0, 2, 1, 7, 6, 4, 9, 5};
printf("Before merge sort: \n");
printArray(array, sizeof(array) / sizeof(int));
mergeSort(array, sizeof(array) / sizeof(int));
printf("\nAfter merge sort: \n");
printArray(array, sizeof(array) / sizeof(int));
return 0;
}
the commented part in the program above is what I want to implement in Assembly language (another file).
My Assembly code (in SystemV x86-64 ABI instruction):
; this is the merge function in assembly
section .text
global merge
merge:
.both: cmp i, rdx
jns .and
.and: cmp j, rcx
jns .checkif
.checkif: cmp [rdi + i * 4], [rsi + j * 4] //error
jns .doif
js .doelse
.doif: mov [r8 + k * 4], [rdi + i * 4]//error
inc i
inc k
jmp .both
.doelse: mov [r8 + k * 4], [rsi + j * 4]//error
inc j
inc k
jmp .both
.doleft: cmp i, rdx
jns .doleftwhile
.doleftwhile: mov [r8 + k * 4], [rdi + i * 4]//error
inc i
inc k
jmp .doleft
.doright: cmp j, rcx,
jns .dorightwhile
.dorightwhile: mov [r8 + k * 4], [rsi + j * 4] // error
inc j
inc k
jmp .doright
mov rax, [rdx + rcx]
ret
section .data
i dd 0
j dd 0
k dd 0
I updated the assembly code and I'm getting the error below:
asm.s:10: error: invalid effective address: impossible segment base multiplier
asm.s:13: error: invalid effective address: impossible segment base multiplier
asm.s:17: error: invalid effective address: impossible segment base multiplier
asm.s:24: error: invalid effective address: impossible segment base multiplier
asm.s:31: error: invalid effective address: impossible segment base multiplier
make: *** [Makefile:25: asm.o] Error 1
Please how do I save each result (element) into a specific index from my code?
PS: sorry for the multiple jumps in the code.