I am trying to translate the following:
Action:
pushl %ebp
movl %esp, %eax
subl $0x32, %esp
movl $0x0, -0x8(%eax)
movl $0x0, -0x4(%eax)
movl -0x4(%eax), %eax
cmpl $0x32(%eax), %ebp
movl -0x4(%ebp), %eax
sall $0x2, %ebp
addl 0x8(%ebp), %ebp
movl (%ebp), %ebp
addl %ebp, -0x8(%eax)
addl $0x1, -0x4(%eax)
What is the best way to translate this code?
For the original question:
mov -0x4(%ebp), %eax # eax = z;
mov 0xc(%ebp), %edx # edx = y;
mov (%edx, %eax, 4), %eax # eax = *(edx + eax + 4)
add $0x3, %eax # eax += 3
movb $0x41, (%eax) # *eax = 'A'
Dry-running the statements give:
y[z + 4][3] = 'A';
Related
I'm trying to translate from C to assembly two functions, one that sort an array of index and one that find the minimum number starting from an index. When I run the program it works , the new array is sorted but at the end it gives me this error
1 2 3 3 4 6 7
*** stack smashing detected ***: ./invidia terminated
Annullato (core dump creato)
this is my .c file
#include <stdio.h>
#include <stdlib.h>
int* sort(int* v, int dim);
int min(int v[], int dim, int t);
int main(){
int v[] = {1,3,2,4,6,7,3};
int dim = 7,i;
int *c = sort(v,dim);
for (i = 0; i<dim; i++)
printf("%d ", c[i]);
return 0;
}
/*int* sort(int* v, int dim){
int i,j=0,t;
int mino,temp;
for (t = 0; t<dim; t++){
for(i=t;i<dim;i++){
mino = min (v,dim,t); <- min number from index t
if (v[i]==mino){
temp = v[j];
v[j] = v[i];
v[i] = temp;
j++;
break;
}
}
}
return v;
}
int min(int v[], int dim, int t){
int i, min = 1000;
for (i=t; i<dim;i++)
if (v[i]<min)
min = v[i];
return min;
}
*/
and my .s file
.globl sort
sort: #v->ebx dim-> esi i->edi, j->ecx t->edx, mino->eax, temp ->ebp
pushl %ebx
pushl %esi
pushl %edi
pushl %ebp
subl $32, %esp
movl 52(%esp), %ebx
movl 56(%esp), %esi
movl $0, %edi
movl $0, %ecx
movl $0, %eax
movl $0, %edx
movl $0, %ebp
FOR1:
cmpl %esi, %edx
jge EXIT
movl %edx, %edi
FOR2:
cmpl %esi, %edi
jge EXIT2
movl %ebx, (%esp)
movl %esi, 4(%esp)
movl %edx, 8(%esp)
movl %ebx, 12(%esp)
movl %eax, 16(%esp)
movl %ecx, 20(%esp)
movl %edx, 24(%esp)
call min
movl 12(%esp), %ebx
movl 20(%esp), %ecx
movl 24(%esp), %edx
cmpl (%ebx, %edi, 4), %eax
jne PSEUDOEND
movl (%ebx, %ecx, 4), %ebp
movl %esi, 12(%esp)
movl (%ebx, %edi, 4), %esi
movl %esi, (%ebx, %ecx, 4)
movl %ebp, (%ebx, %edi, 4)
movl 12(%esp), %esi
incl %ecx
incl %edx
jmp FOR1
PSEUDOEND:
incl %edi
jmp FOR2
EXIT:
movl %ebx, %eax
popl %ebp
popl %edi
popl %esi
popl %ebx
addl $32, %esp
ret
EXIT2:
incl %edx
jmp FOR1
.globl min
min:
movl 4(%esp), %ecx
movl 8(%esp), %edx
movl 12(%esp), %ebx
movl $1000, %eax
FOR:
cmpl %edx, %ebx
jge END
cmpl %eax, (%ecx, %ebx, 4)
cmovl (%ecx, %ebx, 4), %eax
incl %ebx
jmp FOR
END:
ret
to compile I use
gcc -m32 filename.c filename.s -o filename
I don't think that the problem is in the assembly translation because it prints correctly the new array. What could be the problem?
testb $1, %al
je .L3
leal 1(%eax,%eax,2), %eax
jmp .L4
I am given the above assembly code and asked to translate it to c code.
I know what almost all of it is doing, I just don't know how to to do C code for the %al register.
Here Is the rest of the assembly code if it helps
prob2:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
cmpl $1, %eax
je .L1
.L6:
testb $1, %al
je .L3
leal 1(%eax,%eax,2), %eax
jmp .L4
.L3:
shrl %eax
.L4:
cmpl $1, %eax
jne .L6
.L1:
popl %ebp
ret
Doesn't matter here. Bit0 in AL is the same as Bit0 in EAX. The 8-bit operation was surely an optimization of the compiler. So you can read AL as EAX.
So I am trying to convert a bubble sort program from assembly to Y86. I started with this C code and then converted it to assembly:
#include <stdio.h>
void bubble(int *, int);
int main(){
int count = 5;
int data[5]= {3, 2, 6, 1, 9,};
bubble(data, count);
return 0;
}
void bubble(int *data, int count){
int i, last;
for(last = count-1; last > 0; last--){
for (i=0; i < last; i++)
if (data[i+1] < data[i]){
/* Swap adjacent elements */
int t = data[i+1];
data[i+1] = data[i];
data[i] = t;
}
}
}
and this is my Y86 code:
init: irmovl Stack, %esp # Set up stack pointer
irmovl Stack, %ebp # Set up base pointer
call main # call main program
halt # Terminate program
main:
pushl %ebp
rrmovl %esp, %ebp
irmovl -16, %ecx
andl %ecx, %esp
irmovl 48, %ecx
subl %ecx, %esp
irmovl 5, %esi
rmmovl %esi, 44(%esp)
irmovl 3, %esi
rmmovl %esi, 24(%esp)
irmovl 2, %esi
rmmovl %esi, 28(%esp)
irmovl 6, %esi
rmmovl %esi, 32(%esp)
irmovl 1, %esi
rmmovl %esi, 36(%esp)
irmovl 9, %esi
rmmovl %esi, 40(%esp)
mrmovl 44(%esp), %eax
rmmovl %eax, 4(%esp)
mrmovl 24(%esp), %ecx
addl %ecx, %eax
rmmovl %eax, (%esp)
call bubble
irmovl 0, %eax
rrmovl %ebp, %esp
popl %ebp
ret
bubble:
pushl %ebp
rrmovl %esp, %ebp
irmovl 16, %esi
subl %esi, %esp
mrmovl 12(%ebp), %eax
irmovl 1, %esi
subl %esi, %eax
rmmovl %eax, -8(%ebp)
jmp L4
L8:
irmovl 0, %ebx
rmmovl %ebx, -12(%ebp)
jmp L5
L7:
mrmovl -12(%ebp), %eax
irmovl 1, %ecx
addl %ecx, %eax
addl %eax, %eax
addl %eax, %eax
addl %eax, %eax
mrmovl 8(%ebp), %esi
addl %esi, %eax
mrmovl (%eax), %edx
mrmovl -12(%ebp), %eax
addl %eax, %eax
addl %eax, %eax
addl %eax, %eax
mrmovl 8(%ebp), %esi
addl %esi, %eax
mrmovl (%eax), %eax
subl %eax, %edx
jge L6
mrmovl -12(%ebp), %eax
irmovl 1, %esi
addl %esi, %eax
addl %eax, %eax
addl %eax, %eax
addl %eax, %eax
mrmovl 8(%ebp), %esi
addl %esi, %eax
mrmovl (%eax), %eax
rmmovl %eax, -4(%ebp)
mrmovl -12(%ebp), %eax
irmovl 1, %esi
addl %esi, %eax
addl %eax, %eax
addl %eax, %eax
addl %eax, %eax
mrmovl 8(%ebp), %esi
addl %esi, %eax
mrmovl -12(%ebp), %edx
addl %edx, %edx
addl %edx, %edx
addl %edx, %edx
mrmovl 8(%ebp), %esi
addl %esi, %eax
mrmovl (%edx), %edx
rmmovl %edx, (%eax)
mrmovl -12(%ebp), %eax
addl %eax, %eax
addl %eax, %eax
addl %eax, %eax
mrmovl 8(%ebp), %esi
addl %esi, %eax
mrmovl -4(%ebp), %edx
rmmovl %edx, (%eax)
L6:
irmovl 1, %esi
mrmovl -12(%ebp), %ebx
addl %esi, %ebx
L5:
mrmovl -12(%ebp), %eax
mrmovl -8(%ebp), %ebx
subl %ebx, %eax
jl L7
irmovl 1, %esi
mrmovl -8(%ebp), %ebx
subl %esi, %ebx
L4:
irmovl 0, %esi #i = 0
mrmovl -8(%ebp), %ebx
subl %esi, %ebx
jg L8
rrmovl %ebp, %esp
popl %ebp
ret
#stack starts here
.pos 0x200
Stack: .long 0
It seems as though the sign flag is never being raised, and I am not quite sure why this is. When I run the simulator, the elements of the array are never sorted, they just remain in the same position. Any tips on how to fix this would be much appreciated!
I have this IA32 assembly language code I'm trying to convert into regular C code.
.globl fn
.type fn, #function
fn:
pushl %ebp #setup
movl $1, %eax #setup 1 is in A
movl %esp, %ebp #setup
movl 8(%ebp), %edx # pointer X is in D
cmpl $1, %edx # (*x > 1)
jle .L4
.L5:
imull %edx, %eax
subl $1, %edx
cmpl $1, %edx
jne .L5
.L4:
popl %ebp
ret
The trouble I'm having is deciding what type of comparison is going on. I don't get how the program gets to the L5 cache. L5 seems to be a loop since there's a comparison within it. I'm also unsure of what is being returned because it seems like most of the work is done is the %edx register, but doesn't go back to %eax for returning.
What I have so far:
int fn(int x)
{
}
It looks to me like it's computing a factorial. Ignoring the stack frame manipulation and such, we're left with:
movl $1, %eax #setup 1 is in A
Puts 1 into eax.
movl 8(%ebp), %edx # pointer X is in D
Retrieves a parameter into edx
imull %edx, %eax
Multiplies eax by edx, putting the result into eax.
subl $1, %edx
cmpl $1, %edx
jne .L5
Decrements edx and repeats if edx != 1.
In other words, this is roughly equivalent to:
unsigned fact(unsigned input) {
unsigned retval = 1;
for ( ; input != 1; --input)
retval *= input;
return retval;
}
Need some help converting assembly code to C. To my understanding it is a while loop with condition (a < c) but I do not understand the body of the while loop.
movl $0, -8(%ebp) # variable B is at ebp - 8
movl $0, -4(%ebp) # variable A is at ebp - 4
jmp .L3
.L2
movl 8(%ebp), %eax # parameter C is at ebp + 8
addl $2, %eax
addl %eax, %eax
addl %eax, -8(%ebp)
addl $1, -4(%ebp)
.L3
movl -4(%ebp), %eax
cmpl 8(%ebp), %eax
jl .L2
Also explain why you did what you did, thanks.
This is what I got so far
int a,b = 0;
while (a < c) {
c += 4 + 2*c;
a++;
}
If I did all that correctly, then the only thing I don't understand is the line
addl %eax, -8(%ebp)
addl %eax, -8(%ebp) will add the value in eax to the value stored at ebp-8. If you can understand the other add instructions then it's just the same. There's no add 4 intruction so I don't know how you can get the expression 4 + 2*c
movl $0, -8(%ebp) # B = 0
movl $0, -4(%ebp) # A = 0
jmp .L3
.L2
movl 8(%ebp), %eax # eax = C
addl $2, %eax # eax = C + 2
addl %eax, %eax # eax *= 2
addl %eax, -8(%ebp) # B += eax
addl $1, -4(%ebp) # A++
.L3
movl -4(%ebp), %eax
cmpl 8(%ebp), %eax
jl .L2
So the result is as below
int a, b = 0;
while (a < c) {
b += (c + 2)*2;
a++;
}
which is simply
int a = c, b = c*(c+2)*2;