Reputation: 17
I'm trying to convert the following optimised assembly code to C code but keeping as close to the assembly code as possible. I have no idea how to change the movsbl call to C code. My understanding is that it moves a byte with a zero extension into a 32bit register. I have included comments as to what I believe to be happening in the assembly code.
file "my_sieve.c"
.text
.p2align 4,,15
.globl my_sieve
.type my_sieve, @function
my_sieve:
pushl %ebp
movl $4, %eax #eax = 4
pushl %edi
movl $1, %ebp #ebp = 1
pushl %esi
movl $2, %esi #esi = 2
pushl %ebx
movl 24(%esp), %edi #edi = max
cmpl $3, %edi #if edi > 3
jg .L9 #go to L9
jmp .L1 #otherwise go to L1
.p2align 4,,7
.p2align 3
.L6:
addl $1, %esi #esi + 1
movl %esi, %eax #eax = esi
imull %esi, %eax #eax*esi (i*i)
cmpl %edi, %eax #if i>max
jg .L1 #go to L1
.L9:
movl 20(%esp), %ebx #ebx = composite
movl %esi, %edx #edx = esi
sarl $3, %edx #shift edx right 3 bits
movsbl (%ebx,%edx), %ecx #??
movl %esi, %edx #edx = esi
andl $7, %edx #bit-wise AND between 7 & edx, stores result in edx
btl %edx, %ecx #copies edx to ecx
jc .L6 #jump to L6 if carry
.p2align 4,,7
.p2align 3
.L7:
movl %eax, %ecx #ecx = eax
movl %ebp, %ebx #ebx = ebp
andl $7, %ecx #bit-wise AND between 7 & ecx, stores result in ecx
movl %eax, %edx #edx = eax
sall %cl, %ebx #left shift ebx the number of bits held in cl
addl %esi, %eax #eax + esi
movl %ebx, %ecx #ecx = ebx
movl 20(%esp), %ebx #ebx = composite
sarl $3, %edx #sign preserving right shift edx 3 bits
orb %cl, (%ebx,%edx) #8-bit logical OR
cmpl %eax, %edi #compare edi & eax
jge .L7 #jump if greater or equal
jmp .L6 #otherwise jump to L6
.p2align 4,,7
.p2align 3
.L1:
popl %ebx
popl %esi
popl %edi
popl %ebp
ret #return
.size my_sieve, .-my_sieve
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
And my incomplete attempt at creating C code. I need help to fill in the blanks or someone to tell me what I'm attempting is completely wrong.
void my_sieve(char *composite, int max){
long ebp, eax, edi, esi, edi, ecx, edx;
eax = 4;
ebp = 1;
esi = 2;
edi = max;
if(edi > 3)
goto L9;
else
goto L1;
L6:
esi += 1;
eax = esi;
eax = eax*esi;
if(eax > edi)
goto L1;
L9:
ebx = composite;
edx = esi;
//right shift
edx = edx >> 3;
//movsbl
edx = esi;
//bit-wise
edx = edx & 7;
edx = ecx;
if(carry)
goto L6;
L7:
ecx = eax;
ebx = ebp;
//bit-wise
ecs = ecx & 7;
edx = eax;
//left shift
ebx = ebx & 0xFF;
eax += esi;
ecx = ebx;
ebx = composite;
//right shift
edx = edx >> 3;
//8 bit logical OR
if(edi >= eax)
goto L7;
else
goto L6;
L1:
return;
}
Upvotes: 0
Views: 511
Reputation: 100632
I think (int)((int8_t)value)
would do it. Casting between unsigned and signed types of the same size has no effect on the bit pattern. Casting a smaller signed type to a larger one causes a sign extension.
Upvotes: 1