Embedding asm into C programming - c

I am trying to learn assembly my self, and I have been reading different websites first to know the meaning of some registers, if-the, etc, and saw examples on how to use them.
However I don't find it easy to understand. This program finds certain letters and counts them in a board using a bidimensional array. I want to replace the part of the functions void print_results(), and void count() with assembly code since this is very easy in regular C code.
I am not sure how to start so I am more interested on just a good start, specially on how to pass the variable from void read_board() to the function void count() to count the letters found, after that I think I can be on my own.
I appreciate any help, Thank you.
#include <stdio.h>
FILE *inputFilePtr;
char board[7][7];
void usage() {
printf("usage: one filename argument.\n");
}
void read_board() {
int i, j;
for (i=0; i != 7; i++) {
for (j=0; j != 7; j++) {
fscanf(inputFilePtr, "%c", &board[i][j]);
}
fscanf(inputFilePtr, "\n");
}
}
void count() {
__asm__("\
");
}
void print_results() {
}
int main(int argc, char**argv) {
if (argc != 2) {
usage();
return 1;
}
inputFilePtr = fopen(argv[1], "r");
if (inputFilePtr == NULL) {
printf("Couldn't open file, %s\n", argv[1]);
return 1;
}
read_board();
count();
print_results();
return 0;
}

If I get it right, you ask for calling conventions. Maybe this helps: http://en.wikipedia.org/wiki/Calling_convention

I am assuming you want the C-equivalent that does your current asm part.
Since you array board is global and your board size is fixed (7x7), you don't need pass anything to count(). This will do:
void count() {
int i, j, count = 0;
char = 'X'; //Replace with whatever char you want to count
for (i=0; i != 7; i++) {
for (j=0; j != 7; j++) {
if(board[i][j] == c)
count++;
}
}
}
Then simply call count() from wherever you want.
In case if you want to know how to pass parameters to functions (if the board, i & j are not global like your case):
call count as: count(&board[0][0], int i, int j);
Receive the parameters as: void count(char **board, int i, int j)

Not a direct (source) solution in asm, but here are some links you might, or might not have read:
GAS, x86?
X86 Assembly/GAS Syntax, this page has a very easy to read instruction by instruction. Click the X86_Assembly link at top to get the whole "book".
Writing Assembly-Language Functions ... GCC; Has a Examples section with some C-code <-> asm lists.
User guide to the gnu assembler as version 2.17
Using Assembly Language in Linux (http://asm.sourceforge.net), has some info on intel vs AT&T syntax. (as do wiki book above). Also look at the Syscalls with > 5 args. down a bit on the site.

Related

Identify User Defined Function and Library Defined Function

I'm given a task to write a program that checks a piece of code, maximum of 20 lines of code, when the program runs you type in a function name, number of lines of code and type in the codes.
It's meant to search in the code and return if the function name you entered is a Library Function or User Defined Function or No Function if it doesn't find it, the code I've written is below, it doesn't work because I made mistakes and I've been trying to fix it but can't seem to figure it out, and I tried debugging to see where I made mistake, and I figured that in the function SearchRealisation it returns an error that
Run-Time Check Failure #2 - Stack around the variable 'buff' was
corrupted.
This program sample returns Library function instead of user defined function
type the function name: addition
Get count string in code: 9
int addition(int num1, int num2)
{
int result = num1 + num2; //trial
return result;
}
int main()
{
addition(8, 9);
}
Output is Library Function but correct output should be User Defined Function since it was defined in the code
void InputText(int length, char Text[MAX_STRINGS][MAX_COLUMNS])
{
//Repeat by Count String
gets_s(Text[0]);
for (int i = 0; i < length; i++)
gets_s(Text[i]);
//Output a string (starting with � zero and ending with Count String-1)
}
void OutMesseg(int param)
{
//Display one of three messages according to the parameter
if (param == -2)
printf("%s", "user defined function");
else if (param == -1)
printf("%s", "no function");
else
printf("%s", "library function");
}
char* DeleteComentsInString(char Text[MAX_STRINGS], char New[MAX_STRINGS])
{
char* a = strstr(Text, "//");
int len = strlen(Text);
if (a != NULL) len -= strlen(a);
strncpy(New, Text, len);
New[len] = '\0';
return New;
}
bool IsTypeC(char Word[MAX_STRINGS])
{
char ctype[6][MAX_STRINGS] =
{
"int",
"bool",
"char",
"float",
"double",
"void"
};
for (int i = 0; i < 6; i++)
{
if (strstr(Word, ctype[i]) != 0)
return true;
}
return false;
}
int SearchRealisation(int length, char Text[MAX_STRINGS][MAX_COLUMNS], int index_fanc, int& end)
{
int count = 0;
int start = -1;
end = -1;
char buff[MAX_STRINGS];
//Find first {
for (int i = index_fanc + 1; i < length && !count; i++)
{
if (strstr(DeleteComentsInString(Text[i], buff), "{") != NULL)
{
count++;
start = i;
}
}
//find last }
for (int i = start + 1; i < length && count; i++)
{
if (strstr(DeleteComentsInString(Text[i], buff), "{") != NULL)
count++;
else if (strstr(DeleteComentsInString(Text[i], buff), "}") != NULL)
count--;
if (!count)
end = i;
}
if (end == -1)
start = -1;
else
return start;
}
int SearchFunction(int length, char Text[MAX_STRINGS][MAX_COLUMNS], char FunctionName[MAX_COLUMNS], int& end)
{
//bool flag = false;
char commentDel[120];
int in;
for (int i = 0; i < length; ++i)
{
DeleteComentsInString(Text[i], commentDel);
if (strstr(commentDel, FunctionName) != NULL)
{
in = strlen(commentDel) - strlen(strstr(commentDel, FunctionName));
if ((in == 0 || (in != 0 && commentDel[in - 1] == ' ')) && (commentDel[in + strlen(FunctionName)] == ' ' || commentDel[in + strlen(FunctionName)] == '(') && strstr(commentDel, ";") == NULL)
{
return SearchRealisation(length, Text, i, end);
}
}
}
end = -1;
return -1;
}
int SearchResult(int length, char Text[MAX_STRINGS][MAX_COLUMNS], char FunctionName[MAX_COLUMNS])
{
int index;
int end;
int start = SearchFunction(length, Text, FunctionName, end);
if (start == -1)
return -1;
index = SearchFunction(length, Text, FunctionName, end);
if (index < 0)
return -2;
return index;
}
int findFunction(char string[MAX_STRINGS][MAX_COLUMNS], char* functName, int M)
{
return 0;
}
int main()
{
int length = 0;
char Code[MAX_STRINGS][MAX_COLUMNS] = { 0 };
char FunctionName[MAX_COLUMNS];
//char ConstantName[MAX_STRINGS];
printf("type the function name: ");
scanf("%s", &FunctionName);
printf("Get count string in code: ");
scanf("%d", &length);
InputText(length, Code);
printf("\n");
OutMesseg(SearchResult(length, Code, FunctionName));
return 0;
}
Well, you have been given a very difficult task:
There's no way to check this, as functions are resolved by a dynamic process that depends on your filesystem state, which is not available at runtime, after you have already compiled your program.
How do you distinguish a function that is compiled in a separate (but user defined) compilation unit from a system defined function? (e.g. double log(double);) that is defined in a math library? There is no way: the linker gets both from a different place (in the first case it gets it from the place you compiled the separate module, in the system case it gets it from a common library directory that has all the system related functions), but you don't have that information available at runtime).
In order to do this task feasible, you'd at least have the full set of source code files of your program. Preprocess them with the cpp(1) preprocessor (so you bypass all the macro expansion invocations) and then check for all function calls in the source code that are not provided in the full set of sources you have. This is quite similar to what the linker does. After compilation, the compiler leaves an object file with the compiled code, and a symbol table that identifies all the unresolved identifiers, and more important all the provided identifiers from this module. The linker then goes on all your modules trying to solve the unknowns, and for each that it doesn't have a solution in your code, it goes to the library directory to search for it. If it doesn't find it in either one, it fails telling you something is wrong.
In my opinion, you have been given a trap task, as the C language preprocess its input (this is something you should do, as many functions are hidden in the internals of macro bodies), then parse the code (for this, you need to write a C parser, which is no trivial task) to select which identifiers are defined in your code and which aren't. Finally you need to check all the calls you do in the code to divide the set in two groups, calls that are defined (and implemented) in your code, and calls that aren't (implemented, all the calls the compiler needs must be defined with some kind of prototype).
It's my opinion, but you have not a simple task, solvable in a short program (of perhaps one hundred lines) but a huge one.
Thanks a lot to everyone that answered I came up with a way to search the code for function definition and thereby return a value if its defined or not, or not even found, might not be the best solution to the task but works so far

CUDA code not processing if block properly

Stuck at if block right below //step 5, the issue is that the code will not progress into or after the given if block. I need to figure out how to get this particular issue settled before starting the task of generating parallel code. If you run the code you will see one print statement that indicates the value of "one" and another two for "i" and "j". After the if block begins, none of the other print statements are hit. As a result I am quite stuck, I am aware that this is a specific issue, however, I cannot seem to determine it's cause.
Any help is appreciated!
Thanks in advance!
Input file sample.
>386.fasta.screen.Contig1
GAGTTTGATCCTGGCTCAGAATCAACGCTGGCGGCGCGCTTAACACATGC
AAGTCGAACGAGAAAGTGGAGCAATCCATGAGTACAGTGGCGTACGGGTG
AGTAACACGTGGGTAATCTACCTCTTAGTGGGGAATAACTTTGGGAAACC
GAAGCTAATACCGCATAAGCTCGAGAGAGGAAAGCAGCAATGCGCTGAGA
GAGGAGCCCGCGGCCGATTAGCTAGTTGGCAGGGTAAAAGCCTACCAAGG
CAGAGATCGGTAGCCGGCCTGAGAGGGCACACGGCCACACTGGCACTGAA
ACACGGGCCAGACTCCTACGGGAGGCAGCAGTGGGGAATCTTGCACAATG
GGGGCAACCCTGATGCAGCGACGCCGCGTGAGCGATGAAGCCCTTCGGGG
TGTAAAGCTCTTTCGTCAGGGAAGATAGTGACGGTACCTGGAGAAGCAGC
TGCGGCTAACTACGTGCCAGCAGCCGCGGTAATACGTAGGCAGCGAGCGT
TGTTCGGAGTTACTGGGCGTAAAGGGTGTGTAGGCGGTTGTTTAAGTTTG
GTGTGAAATCTCCCGGCTCAACTGGGAGGGTGCGCCGAATACTGAGCGAC
TAGAGTGCGGGAGAGGAAAGTGGAATTCCTGGTGTAGCGGTGAAATGCGT
AGATATCAGGAGGAACACCGGTGGTGTAGACGGCTTTCTGGACCGTAACT
GACGCTGAGACACGAAAGCGTGGGTAGCAAACAGGATTAGATACCCTGGT
AGTCCACGCCCTAAACGATGCATATTTGGTGTGGGCAGTTCATTCTGTCC
GTGCCGGAGCTAACGCGTTAAATATGCCGCCTGGGGAGTACAGTCGCAAG
GCTGAAACTCAAAGGAATTGACGGGGGCCCGCACAAGCGGTGGAGCATGT
GGTTTAATTCGACGCAACGCGAAGAACCTTACCTGGGCTCGAACGGCTTC
CCAACGCCGGTAGAAATATCGGTACCCCGCAAGGGGGTGGAATCGAGGTG
CTGCATGGCTGTCGTCAGCTCGTGTCGTGAGATGTTGGGTTAAGTCCCGC
AACGAGCGCAACCCTTGTCCTGTGTTGCCATGCCGCAAGGCGGCACTCGC
AGGAGACCGCCAGCGATAAGCTGGAGGAAGGTGGGGATGACGTCAAGTCC
TCATGGCCTTTATGTCCAGGGCTACACACGTGCTACAATGGCCGGTACAA
AGCGTCGCTAACCTGCGAAGGGGAGCCAATCGCAAAAAACCGGTCTCAGT
TCGGATTGCAGGCTGCAACCCGCCTGCATGAAGCTGGAATCGCTAGTAAT
GGCAGATCAGCACGCTGCCGTGAATACGTTCCCGGGCCTTGTACACACAT
/********************************
Based on code by:
Lorenzo Seidenari (sixmoney#virgilio.it)
*********************************/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#define MAX_SEQUENCE_LENGTH 100000
int n;
int m;
int levenshtein_distance(char *s,char*t);
int minimum(int a,int b,int c);
//-----------------------------------------------------------------------------
void cleanString(char string[]) {
//Removes all spaces from string pointed to by "string", converts characters
//to uppercase, and deletes a terminating newline character.
int i, current;
int length = strlen(string);
current = 0;
for(i=0;i<length;i++) {
if(string[i]=='\n') {
string[current++] = '\0';
break;
}
else if(string[i]!=' ') {
string[current++] = toupper(string[i]);
}
}
}
//-----------------------------------------------------------------------------
int importFASTA(char *filename, char *sequence) {
//Reads a file, located at path specified by "filename", containing a FASTA
//sequence. It finds the first full, complete sequence in the file, stores
//it in "sequence", and returns the length of the sequence, or -1 on failure.
FILE *fastaFile;
char input[256];
int readFlag; //set to 1 once a sequence has been read in
int length;
//open the file
if((fastaFile = fopen(filename, "r")) == NULL) {
return -1;
}
sequence[0] = '\0';
//read the full first sequence, discarding unnecessary headers
readFlag=0;
length = 0;
while(fgets(input,256,fastaFile)!=NULL) {
//is it a header or a comment?
if(input[0]=='>' || input[0]==';') {
if(readFlag) break;
else continue;
}
else readFlag = 1;
cleanString(input);
length += strlen(input);
strncat(sequence,input,MAX_SEQUENCE_LENGTH-length - 1);
}
//Add a terminatng null character, just in case
sequence[length] = '\0';
fclose(fastaFile);
return length;
}
/****************************************/
/*Implementation of Levenshtein distance*/
/****************************************/
__global__ void levenshtein_distance(char *s,char*t, int one, int two)
/*Compute levenshtein distance between s and t*/
{
//Step 1
int k,i,j,cost,*d;
int distance = 0;
if(one!=0&&two!=0)
{
d=(int *)malloc((sizeof(int))*(two+1)*(one+1));
two++;
one++;
//Step 2
for(k=0;k<one;k++){
d[k]=k;
}
for(k=0;k<two;k++){
d[k*one]=k;
}
//Step 3 and 4
for(i=1;i<one;i++){
for(j=1;j<two;j++)
{
//Step 5
printf("%d %d %d\n", one, i, j);
if(s[i-1]==t[j-1]){
cost=0;
printf("%d %d %d\n", one, i, j);
}
else{
cost=1;
printf("%d %d %d\n", one, i, j);
}
printf("%d %d %d\n", one, i, j);
//Step 6
int min = d[(j-1)*one+i]+1;
if (d[j*one+i-1]+1 < min)
min = d[j*one+i-1]+1;
if (d[(j-1)*one+i-1]+cost < min)
min = d[(j-1)*one+i-1]+cost;
d[j*one+i] = min;
}
distance=d[one*two-1];
free(d);
printf("%d\n", distance);
}
}
else
printf ("-1");
}
int main(int argc, char *argv[]) {
char A[MAX_SEQUENCE_LENGTH+1];
char B[MAX_SEQUENCE_LENGTH+1];
if(argc < 3) {
printf("Usage: new_edit_distance <sequence1> <sequence2>\n");
printf("<sequence1>: file containing the first sequence, FASTA format\n");
printf("<sequence2>: file containing the second sequence, FASTA format\n");
return EXIT_FAILURE;
}
n = importFASTA(argv[1],A);
m = importFASTA(argv[2],B);
levenshtein_distance<<<1, 1>>>(A,B, n, m);
cudaDeviceSynchronize();
printf ("%s\n", cudaGetErrorString(cudaGetLastError()));
return EXIT_SUCCESS;
}
I get it now. You took straight serial C/C++ code, dropped it into a kernel, intended to run that kernel as a single thread, and then want to proceed from there.
The idea is plausible, but you're missing a key fact about CUDA and GPUs: they can't directly access host memory.
So when you set up A and B like this:
char A[MAX_SEQUENCE_LENGTH+1];
char B[MAX_SEQUENCE_LENGTH+1];
....
n = importFASTA(argv[1],A);
m = importFASTA(argv[2],B);
those are ordinary variables that live in host memory. GPU (ordinary CUDA) code can't directly access host memory. So when you pass those pointers to a kernel like this:
levenshtein_distance<<<1, 1>>>(A,B, n, m);
the GPU code will try and dereference those A and B pointers and will fault (unspecified launch failure).
Every CUDA program has the following basic sequence:
copy data to the GPU
perform computations on the GPU
copy results back
You've tried to do step 2 without step 1. It won't work.
Since I'm not able to run your program since I don't have valid input files, I'll make the following suggestion. I assume you know little or nothing about CUDA. Try adding lines like this:
n = importFASTA(argv[1],A); // no change
m = importFASTA(argv[2],B); // no change
char *d_A, *d_B; // add this line
cudaMalloc(&d_A, MAX_SEQUENCE_LENGTH+1); // add this line
cudaMalloc(&d_B, MAX_SEQUENCE_LENGTH+1); // add this line
cudaMemcpy(d_A, A, MAX_SEQUENCE_LENGTH+1, cudaMemcpyHostToDevice); // add
cudaMemcpy(d_B, B, MAX_SEQUENCE_LENGTH+1, cudaMemcpyHostToDevice); // add
levenshtein_distance<<<1, 1>>>(d_A,d_B, n, m); //modify parameters
n and m don't need to be handled any differently since you are passing those by value.
And add proper cuda error checking to your code.
EDIT: after some further analysis, it's clear that this sequence is not correct:
distance=d[one*two-1];
free(d);
printf("%d\n", distance);
}
}
You are freeing d on every iteration of the i loop. That cannot possibly be correct. I suggest you go back to square one and get your serial code working first, in ordinary serial C code, before dropping it into a cuda kernel this way. If you move that free statement outside the i loop, then your kernel runs for a very very long time. Be advised that in-kernel printf is limited in the amount of output that can be easily generated.
I'm not going to debug your code any further for you. Get your serial code working first, then figure out a way to create a kernel without massive quantities of printout.
A final comment: I said above your approach is "plausible". That it means it could be made to work, i.e produce the same behavior as the same code executing on the host. It does not mean it will run fast. This is not how you get acceleration out of a GPU (running a single block of a single thread). I assume you already know this based on your comment "how to get this particular issue settled before starting the task of generating parallel code." But I think the disclaimer is appropriate anyway.

User entered string run a particular function in c

Guys so I'm working on the web service assignment and I have the server dishing out random stuff and reading the uri but now i want to have the server run a different function depending on what it reads in the uri. I understand that we can do this with function pointers but i'm not exactly sure how to read char* and assign it to a function pointer and have it invoke that function.
Example of what I'm trying to do: http://pastebin.com/FadCVH0h
I could use a switch statement i believe but wondering if there's a better way.
For such a thing, you will need a table that maps char * strings to function pointers. The program segfaults when you assign a function pointer to string because technically, a function pointer is not a string.
Note: the following program is for demonstration purpose only. No bounds checking is involved, and it contains hard-coded values and magic numbers
Now:
void print1()
{
printf("here");
}
void print2()
{
printf("Hello world");
}
struct Table {
char ptr[100];
void (*funcptr)(void)
}table[100] = {
{"here", print1},
{"hw", helloWorld}
};
int main(int argc, char *argv[])
{
int i = 0;
for(i = 0; i < 2; i++){
if(!strcmp(argv[1],table[i].ptr) { table[i].funcptr(); return 0;}
}
return 0;
}
I'm gonna give you a quite simple example, that I think, is useful to understand how good can be functions pointers in C. (If for example you would like to make a shell)
For example if you had a struct like this:
typedef struct s_function_pointer
{
char* cmp_string;
int (*function)(char* line);
} t_function_pointer;
Then, you could set up a t_function_pointer array which you'll browse:
int ls_function(char* line)
{
// do whatever you want with your ls function to parse line
return 0;
}
int echo_function(char* line)
{
// do whatever you want with your echo function to parse line
return 0;
}
void treat_input(t_function_pointer* functions, char* line)
{
int counter;
int builtin_size;
builtin_size = 0;
counter = 0;
while (functions[counter].cmp_string != NULL)
{
builtin_size = strlen(functions[counter].cmp_string);
if (strncmp(functions[counter].cmp_string, line, builtin_size) == 0)
{
if (functions[counter].function(line + builtin_size) < 0)
printf("An error has occured\n");
}
counter = counter + 1;
}
}
int main(void)
{
t_function_pointer functions[] = {{"ls", &ls_function},
{"echo", &echo_function},
{NULL, NULL}};
// Of course i'm not gonna do the input treatment part, but just guess it was here, and you'd call treat_input with each line you receive.
treat_input(functions, "ls -laR");
treat_input(functions, "echo helloworld");
return 0;
}
Hope this helps !

How can I pass an array as parameters to a vararg function?

I have some code that looks like this:
uint8_t activities[8];
uint8_t numActivities = 0;
...
activities[numActivities++] = someValue;
...
activities[numActivities++] = someOtherValue;
...
switch (numActivities)
{
0 : break;
1 : LogEvent(1, activities[0]); break;
2 : LogEvent(1, activities[0], activities[1]); break;
3 : LogEvent(1, activities[0], activities[1], activities[2]); break;
// and so on
}
where LogEvent() is a varargs function.
Is there a more elgant way to do this?
[Update] Aplogies to #0x69 et al. I omitted to say that there are many cases where LogEvent() could not take an array as a parameter. Sorry.
There's no standard way to construct or manipulate va_args arguments, or even pass them to another function (Standard way to manipulate variadic arguments?, C Programming: Forward variable argument list). You'd be better off seeing if you can access the internal routines of LogEvent.
pass a pointer to the array of ints and a number of ints instead
#include <stdio.h>
void logevent(int n, int num, int *l) {
int i;
for (i=0; i<num; i++) {
printf("%d %d\n",n,*(l++));
}
}
int main() {
int activities[8];
activities[0]=2;
activities[1]=3;
activities[2]=4;
int num=3;
int n=1;
logevent(n,num, activities);
printf("=========\n");
n=2;
activities[3]=5;
num=4;
logevent(n,num, activities);
}

what's the meaning of the circle node in pdgs which is generated by frama-c

I use frama-c tool to analyse the code below.
int main (int argc, char *argv[])
{
int i,a;
for (i = 0; i < 100; i += 1)
{
a=0;
if (a==0)
{
continue;
}
else
{
break;
}
}
return 0;
}
the cmd is
frama-c -pdg -dot-pdg graph main.c
My question is about the control dependence. what's the circle node means? I try to explain the "while" node, maybe it stand for one time loop , because a loop start from "i<100",so there a control dependence ("i<100" ------o "while" ). Is what I guess right ? but what is the "break" node mean? I guess that node "goto __Cont;" is related to the "break;" statement in the "else" block.
I think I have no clear abstract model in my head for understanding the control dependence completely and accurately . Would you help me or give me any suggestion ?. Many Thanks in Advance Tao.
Use the command frama-c -print main.c to see how the program was translated (I include the translated version below).
The statement goto __Cont; in the normalized version is the translation of continue; in the original.
And, as Binyamin said, the for loop was normalized into a while loop.
int main(int argc, char **argv)
{
int __retres;
int i;
int a;
i = 0;
while (i < 100) {
a = 0;
if (a == 0) { goto __Cont; }
else { break; }
__Cont: /* internal */ i ++;
}
__retres = 0;
return (__retres);
}
Most of it is self explanatory:
circle - flow control (branching)
rhombus - condition (a == 0 etc.)
square - assignment
Your for loop was translated to a while loop

Resources