Inline Samples
Следующий пример ожидает ввода 4-значного числа , передает его в качестве
строки в подпрограмму и возвращает целое число .
Для извлечения в подпрограмме входящего аргумента идет обращение
к стеку по смещению 8(%ebp) :
#include < stdio.h>
int Atoi(char *num)
{
__asm__(
"movl 8(%ebp),%ebx \n" // Set ebx to first element in array
"xorl %eax,%eax \n" // set eax (counter) to NULL
"xorl %ecx,%ecx \n" // set ecx (sum) to NULL
"xorl %edx,%edx \n" // set edx to NULL
".loop: \n" // forloop section
"addl $-48,(%eax,%ebx) \n" // add -48 to array element(conversion)
"imull $10,%ecx \n" // multiply by 10(shift left)
"addb (%eax,%ebx),%ecx \n" // add next array element to sum
"incl %eax \n" // increment counter
"cmpl $3,%eax \n" // compare counter to 3
"jle .loop \n" // go to forloop if i is less than or = 3
"movl %ecx,%eax \n" // move sum to eax reg.
);
}
void main()
{
int i;
char num[4];
printf("Enter in a four-digit number: ");
for(i = 0; i < 4; i++)
num[i] = getchar();
printf("\nConverting...");
i = Atoi(num);
printf("\nThe integer: %i\n", i);
}
Следующий пример вычисляет факториал :
#include < stdio.h>
unsigned long fact(unsigned long x)
{
__asm__ (
"xorl %ecx,%ecx \n" // initialize ecx to NULL
"movl 8(%ebp),%ecx \n" // copy ecx to long int x
"movl %ecx,%edx \n" // copy edx to ecx
".loop: \n" // forloop
"cmpl $1,%ecx \n" // compare ecx with 1
"jbe .exit \n" // exit if ecx is below or = to 1
"decl %ecx \n" // decrement ecx
"imull %ecx,%edx \n" // multiply ecx by edx, store in edx
"jmp .loop \n" // goto forloop
".exit: \n" // exit
"movl %edx,%eax \n" // return value to eax
);
}
void main()
{
unsigned long factorial;
unsigned long x;
printf("Please enter an integer below 13 for the factorial to be computed: ");
scanf("%ld", &x);
factorial = fact(x);
printf("\nThe factorial of %ld is %ld.\n", x, factorial);
}
Следующий пример конвертирует строку из нижнего регистра в верхний :
#include < stdio.h>
char string[16];
void lowtocap(char string[])
{
__asm__("movl 8(%ebp),%edx \n" //copy address of array into edx
"xorl %eax,%eax \n" //set eax to NULL
".loop: \n" //forloop
"cmpb $0,(%eax,%edx) \n" //init. eax to 0, compare eax to edx
"je .exit \n" //exit if equal
"addb $-32,(%eax,%edx) \n"//add -32 to eax(element) of edx(array)
"incl %eax \n" //incremnt i
"cmpl $15,%eax \n" //compare length of array to i
"jle .loop \n" //goto loop if eax is less than or = to 15
".exit: \n" //exit
);
}
void main(void)
{
printf("Enter a lowercase string less than 15 characters: ");
gets(string);
lowtocap(string);
printf("%s\n",string);
}
Следующий пример - эмуляция умножения путем сложения .
Показано , как вместо локальных параметров использовать в inline-процедуре
глобальные по имени :
#include < stdio.h>
int a,b;
int multiply( void )
{
__asm__(
"movl a, %ecx \n" // move a into ecx reg.
"movl b, %eax \n" // move b into eax reg.
"cmpl $0,%ecx \n" // compare a with zero
"je .zero \n" // go to .zero if it equals zero
"cmpl $0,%eax \n" // compare b with zero
"je .zero \n" // go to .zero if it equals zero
"movl %eax, %ebx \n" // move b into ebx reg.
"movl $1, %edx \n" // move 1 into edx reg.,
"cmpl %ecx, %edx \n" // compare a with edx (counter)
"jge .end \n" // if edx is greater or = then end
".loop: \n" // for loop section
"addl %ebx, %eax \n" // add ebx to eax and store in eax
"incl %edx \n" // increment edx
"cmpl %ecx, %edx \n" // compare ecx (a) with edx
"jl .loop \n" // if less than, do loop again
"jmp .end \n" // go to the end
".zero: \n" // if equal to zero section
"movl $0,%eax \n" // copy set eax(product) equal to zero
".end: \n" // end
);
};
void main()
{
char buf[20];
printf("Enter the first number to multiply: ");
a=atoi(gets(buf));
printf("Enter the second number to multiply: ");
b=atoi(gets(buf));
printf("The product is: %i\n",multiply());
}
Пример проверки строки , является ли она палиндромом -
процедура с 2-мя параметрами :
#include < stdio.h>
#include < string.h>
int palindrome ( char string[], int length)
{
__asm__(
"movl 8(%ebp),%esi \n" // put address of string into esi
"movl 12(%ebp),%ecx \n" // put length of string into ecx
"xorl %ebx, %ebx \n" // set ebx to zero
".loop: \n" // forloop
"cmpl %ecx, %ebx \n" // when ebx is greater than ecx, jump to pal section
"jg .pal \n" // goto pal section
"movl %ecx, %eax \n" // copy the ecx to the eax
"movl %ebx, %edx \n" // copy the ebx to the edx
"decl %ecx \n" // decrement ecx
"incl %ebx \n" // encrement ebx
"mov (%esi,%eax),%al \n" // al is equal to the string[eax]
"mov (%esi,%edx),%ah \n" // ah is equal to the string[edx]
"cmp %ah,%al \n" // compare the letters
"je .loop \n" // if they match, check the next pair
"xorl %eax,%eax \n" // else its not a palindrome
"jmp .exit \n" // goto exit
".pal: \n"
"movl $1,%eax \n" // Return true
".exit: \n"
);
}
void main()
{
char string[30];
int i;
printf ("Enter palindrome: ");
gets(string);
i = strlen(string);
if(palindrome(string,i-1))
{
printf("%s is a palindrome.\n",string);
}
else
{
printf("%s is not a palindrome.\n",string);
}
}
Следующий пример - переворачивание строки . Для возвращения результата используется
глобальная переменная - массив символов , индексом которого служит регистр ecx :
#include < stdio.h>
char temp[16];
void rev(char string[], int size)
{
__asm__(
"movl 8(%ebp),%ebx \n" //copy address of string into ebx
"xorl %ecx,%ecx \n" //set ecx(counter) to NULL
"movl 12(%ebp),%edx \n" //copy address of size to edx
"decl %edx \n" //decrement edx
"js .exit \n" //if S is 1 then exit
".loop: \n" //forloop
"movb (%edx,%ebx),%al \n" //set l = to element in ebx
"movb %al,temp(%ecx) \n" //set tmp = l
"incl %ecx \n" //increment ecx
"decl %edx \n" //decrement edx
"jns .loop \n" //continue forloop
".exit: \n" //exit
"movb $0,temp(%ecx) \n" //set NULL on end of tmp array
);
}
void main()
{
char string[16];
printf("Enter a string (max 15 characters): ");
gets(string);
rev(string, strlen(string));
printf("%s\n",temp);
}
Нахождение максимального числа в массиве :
/******************************************************************************
Program file name: sort.c
Class: CPTR 215
Assignment: #14
Language: C++ and Assembly
Operating System: Linux
Programmer: Sam Rodriguez
Date Written: 12/11/98
Revisions:
Description: sorts an array in order to find biggest integer
Inputs: 10 integers
Outputs: greatest integer
Special requirements: none
Criteria Grades (0 to 5 points each):
Program Design: _____ x 5% = _____
Program Execution: _____ x 4% = _____
Specification Satisfaction: _____ x 4% = _____
Coding Style: _____ x 3% = _____
Comments: _____ x 2% = _____
Creativity: _____ x 2% = _____
Late Submission Penalty: _____
Total % = _____
Overall Program Grade:
Program's Point Value = _____
Program's Score = _____
Comments:
******************************************************************************/
#include
int sort(int array[])
{
__asm__(
"movl 8(%ebp),%ecx\n" //copy address of array to the ecx reg.
"xorl %eax,%eax\n" //set the eax(temp) to NULL
"xorl %edx,%edx\n" //set the edx(counter) to NULL
".if:\n" //if section
"cmpl %eax,(%ecx,%edx,4)\n" //compare element with eax
"jle .loop\n" //if smaller or equal skip ahead
"movl (%ecx,%edx,4),%eax\n" //if bigger set eax equal to it
".loop:\n" //forloop
"incl %edx\n" //increment counter
"cmpl $9,%edx\n" //check exit cond. for forloop
"jle .if\n" //go to "if" if edx was less than 10
);
}
void main ( )
{
int array[10];
int i;
char buf[20];
printf("Please enter 10 integers.\n");
for ( i = 0; i<10; i++)
{
printf("Element %i: ",i+1);
array[i]=atoi(gets(buf));
}
printf("The largest number is %i\n",sort(array));
}
|