I am stuck with converting C code into assembly. Here is the code that I need to convert:
#include <stdio.h>
define N 50 int x[N], y[N], z[2 * N];
void convolve(int[], int[], int[], int);
int main(void)
{
int i, n;
printf("Enter vector size (<=%d): ", N);
scanf("%d", &n);
printf("Enter first vector (%d elements):\n", n);
for (i = 0; i < n; i++)
**scanf("%d", &x[i]);
**printf("Enter second vector (%d elements):\n", n);
for (i = 0; i < n; i++)
scanf("%d", &y[i]);
convolve(x, y, z, n);
printf("Convolution:\n");
for (i = 0; i < ((n + n) - 1); i++)
printf("%d ", z[i]);
printf("\n");
return 0;
}
void convolve(int x[], int y[], int z[], int n)
{
int i, j;
for (i = 0; i < ((n + n) - 1); i++)
z[i] = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
z[i + j] += x[i] * y[j];
return;
}
I am stuck at this line:
scanf("%d", &x[i]);
How do I insert into array?
Here is what I have so far:
.data
.align 4
state: .long 0
.bss
N = 50
int x[N], y[N], z[2*N]
.data
.equ N, 50
.comm i,4,4 #int b
.comm n,4,4 #int n
.comm j,4,4 #int j
.comm x,N*4,4 #int x[N] where N is 50
.comm y,N*4,4 #int x[N] where N is 50
.comm z,N*8,4 #int x[N] where N is 100
.section .rodata #to format strings
fmt0: .string "Enter vector size (<=%d): "
fmt1: .string "%d"
fmt2: .string "Enter first element (%d elements):\n"
fmt3: .string "Enter second element (%d elements):\n"
fmt4: .string "Convolution:\n"
fmt5: .string "\n"
fmt6: .string .%d .
.text
.globl main
main:
pushl %ebp #prolog
movl %esp, %ebp
pushl %esi #save callee-save registers %esi, %edi, and %ebx onto stack
pushl %edi # where %esi at -4(%ebp),%edi at -8(%ebp), and %ebx at -12(%ebp)
pushl %ebx
pushl %eax #for array where %eax at -16(%ebp)------------------------------
/* Allocate space for i and n on the stack */
subl $8, %esp
/* i is at address -20(%ebp) */
/* n is at address -24(%ebp) */
pushl $fmt0 #push fmt0
call printf #printf("Enter vector size (<=%d): ")
addl $4, %esp #deallocate parm to printf
leal -24(%ebp), %ebx #%ebx = address of n
pushl %ebx #push address of n
pushl $fmt1 #push fmt1 "%d"
call scanf #scanf ("%d", &n)
addl $8, %esp #dealoccate parms for scanf
pushl $fmt2 #push fmt2
call printf #printf("Enter first element (%d elements):\n")
addl $4, %esp #deallocate parm to printf
movl $0, -20(%ebp) #i=0
movl -20(%ebp), %edi #%edi=i
movl -24(%ebp), %esi #esi=n
cmpl %esi, %edi #compare i:n
jg for_done #jump to for_done if i>n
for_loop:
pushl %edi #push i
pushl %esi #push n
pushl %eax #push array
pushl $fmt1 #push fmt1 ("%d")
call scanf #scanf("%d", n)
addl $8, %esp #dealocate parms to scanf
movl (address of x,%edi,4), %eax------------------------------------------------------
incl %edi #%edi++ (i++)
movl %edi,-20(%ebp) #i=%edi
compl %esi, %edi #compare i:n
jle for_loop #jump to for_loop if i<n
for_done:
addl $8, %esp #deallocate local vars from stack
popl %ebx #restore %ebx
popl %edi #restore %edi
popl %esi #restore %esi
/*next loop for second vector*/
pushl %esi #save callee-save registers %esi, %edi, and %ebx onto stack
pushl %edi # where %esi at -4(%ebp),%edi at -8(%ebp), and %ebx at -12(%ebp)
pushl %ebx
pushl $fmt3 #push fmt3
call printf #printf("Enter second element (%d elements):\n")
addl $4, %esp #deallocate parm to printf
movl $0, -20(%ebp) #i=0
movl -20(%ebp), %edi #%edi=i
movl -24(%ebp), %esi #esi=n
cmpl %esi, %edi #compare i:n
jg for_done #jump to for_done if i>n
for_loop:
pushl %edi #push i
pushl %esi #push n
pushl %eax #push array
pushl $fmt1 #push fmt1 ("%d")
call scanf #scanf("%d", n)
addl $8, %esp #dealocate parms to scanf
movl (address of y,%edi,4), %eax------------------------------------------------------
incl %edi #%edi++ (i++)
movl %edi,-20(%ebp) #i=%edi
compl %esi, %edi #compare i:n
jle for_loop #jump to for_loop if i<n
for_done:
addl $8, %esp #deallocate local vars from stack
popl %ebx #restore %ebx
popl %edi #restore %edi
popl %esi #restore %esi
leave #epilog
ret
convolve:
pushl %ebp #prolog
movl %esp, %ebp
pushl %esi #save callee-save registers %esi, %edi, and %ebx onto stack
pushl %edi # where %esi at -4(%ebp),%edi at -8(%ebp), and %ebx at -12(%ebp)
pushl %ebx
/* Allocate space for x, y, z, n, i, and j on the stack */
subl $24, %esp
/* x is at address 4(%ebp) */
/* y is at address 8(%ebp) */
/* z is at address 12(%ebp) */
/* n is at address 16(%ebp) */
/* i is at address -16(%ebp) */
/* n is at address -20(%ebp) */
movl $0, -16(%ebp) #i=0
movl -16(%ebp), %edi #%edi=i
movl -20(%ebp), %esi #esi=n
addl %esi, %esi #2 times n
subl $1, %esi #2n - 1
cmpl %esi, %edi #compare i:n
jg for_done #jump to for_done if i>n
leainstruction. You should of course pass the address ofx[i]to scanf, and you should not pushiornsince this invocation doesn't use those and will unbalance your stack.gcc -O0 -S ...to see the GCC assembly code, 2) Check out Jonathan Bartlett's excellent book about Linux/Assembler: Programming from the Ground Up.-O0is pretty noisy and hard to read, since it stores and reloads all variables between expressions. I think modern debug-info formats can tell debuggers when a variable is live in a register, because ` -Og` doesn't do that. It means "optimize for debugging", and makes less noisy asm that still does pretty much what the source says. It's easier to keep track of what's going on when you see the same register used for a few insns in a row, instead of having to notice that it's the same address.-fverbose-asmis sometimes helpful, too. Also see gcc.godbolt.org.