8

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
24
  • 1
    Hint: look at the lea instruction. You should of course pass the address of x[i] to scanf, and you should not push i or n since this invocation doesn't use those and will unbalance your stack. Commented Nov 12, 2015 at 18:41
  • 4
    TWO SUGGESTIONS: 1) compile your C program with 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. Commented Nov 12, 2015 at 18:58
  • 2
    I did compile it with gcc -O0 -S, but it is hard to understand, that's just not what I am learning in my class...:( Commented Nov 12, 2015 at 19:00
  • 2
    @paulsm4:-O0 is 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-asm is sometimes helpful, too. Also see gcc.godbolt.org. Commented Nov 12, 2015 at 19:58
  • 1
    "-S" is for converting C into asm via gcc. gcc.godbolt.org suggested that -fverbose-asm" can be a good switch to use in addition to "-S". If assembly is new to you, I strongly urge you to read Bartlett's book. It's available free, on-line via the link above. Commented Nov 12, 2015 at 21:21

1 Answer 1

1

I can't help but notice you've got two different for_loop and for_done defined; you might want to differentiate them somehow.

as per some of the other suggestions, maybe something like this, for example, could work:

for_loop1:
     pushl   %edi           #push i
     pushl   %esi           #push n
     leal    x(,%edi,4), %eax
     pushl   %eax           #push array

...

for_loop2:
     pushl   %edi           #push i
     pushl   %esi           #push n
     leal    y(,%edi,4), %eax
     pushl   %eax           #push array
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.