Using stdlib.h functions directly in assembly - c

I have to do an assembly (x86) program that takes 2 long numbers from user input, adds them using a function and then prints the result. When I use the read syscall I get a string in ASCII hex code and I can't add the numbers like that. So I wanted to use atol that is a function of stdlib.h to convert the string to long. How can I include libraries in assembly? Is there another way to do this?
I have already tried:
.file "stdlib.h" (I have the lib in the current directory)
error: undefined reference to atol'
compiling stdlib.h with the .s file together using clang
error: stdlib.h: file not recognized: File format not recognized
making a .c file with only #include<stdlib.h> and compiling it with the .s file
error: undefined reference to `atol'
the comads I run are
clang function.s -c -g
ld function.o -o function

The linker complains that atol has not been found because it is a function in the C library, but you didn't tell the linker to add the C library to your program during linking. To fix this, pass -lc to the linker to add the C library during linking:
ld -o function function.o -lc
It is very important that -lc goes last, otherwise the link might not work. This is because the linker picks functions from libraries in the order you specify them. When you specify -lc before function.o, it ignores the library as it doesn't need anything from it right now. Then it sees function.o with an undefined atol and doesn't find a definition, causing the link to fail.
Lastly, when you use the C library, you should start your program from the main function (i.e. rename _start to main) like a normal C program and link through the C compiler:
clang -g -o function function.s
This causes the C library to be linked in automatically and makes initialises it correctly, preventing some weird bugs. If you use any IO functions like printf from the C library, you should also end your program by calling exit so the standard IO streams are flushed correctly.
Note that the stdlib.h file is a red herring. Header files are not needed for programming in assembly. Their purpose is to tell the C compiler what the type of some functions are. This is not needed if you do not use the C compiler. The .file directive does not do what you expect it does.

You added a compilation unit (the .c file) to the project. This introduces the prototype of the functions in the included header file "stdlib.h". What you want is reference to that function. This should be introduced in the assembler file that shall use the function.
Adding a extern statement to the assembler file should do the job. You don't need the C file with the include. You will have to add the corresponding library in the linker settings. But even if you successfully link an EXE file, you probably get a problem, since some functions in the stdlib needs an initialization. You must also call the C run-time initialization function.

Related

How to call ran2() function in c

Are ran1,ran2, ran3 functions are included in the library ? Does these needs some header file or package ? How to mention in the program and how to call .
I just know the basic programmings .I am trying to learn random variable generators .I have looked in the book numerical recipe there are three functions ran1,ran2 and ran3.I want to know how this function called or used in the program ? How to mention this functions in my program?
In order to use a function (ran1(), ran2() or ran3()) from a library X you usually have to include the header in your_file.c:
#include <X.h>
Tell the compiler which directory to find said header if it's in a non-standard location. Say, the header is path/include/X.h, then you would compile the file with:
gcc -Ipath/include -c your_file.c
And you link the library by using the -L to tell where the dynamic library is located, say, path/lib/libX.so:
gcc -Lpath/lib -lX your_file.o -o your_file
If your library ships with a .pc file then you use pkg-config --cflags libX for the compilation, and pkg-config --libs libX for linking. Note there is some variability in the naming of the pc file so look at what your library uses if any.

(Cygwin) C program linked to custom header file having memory problems when trying to execute

I am using Cygwin. I have two files in the same directory, test.c and iah202_graphics.h. test.c uses functions from the header file, where I have used #include "iah202_graphics.h". I have added the Cygwin directory to my Environment Variables (PATH) already.
However I receive these errors for every function call:
$ gcc -o test test.c
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): undefined reference to `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): relocation truncated to fit:
R_X86_64_PC32 against undefined symbol `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x4a): undefined reference to
`draw_line'.
collect2: error: ld returned 1 exit status.
It's having trouble linking to the header file even though I've simply stated which file to use in the local directory. I don't understand what I'm doing wrong?
Undefined reference to 'blah' is a linker error rather than a compiler error and is almost always caused by not including a needed library.
Including a header file in your source file does not usually link in the code required to provided the functions declared in that header.
For example, were you to prevent linking of the C runtime library, you could include stdio.h as many times as you wanted to, and still not be able to resolve printf.
Bottom line, you generally need two steps:
include the relevant header file in your source code so it knows about the declarations of things provided; and
link against the relevant library or object file so it has access to the definitions of the things provided.
That could be something as simple as:
gcc -o test -I/path/to/iah202includes test.c -L/path/to/iah202libs -liah202
where -I indicates where include files can be found, -L adjusts the search path for library files, and -l actually specifies the library file to use.
Even simpler is if you have the source file for the graphics stuff (which seems to be the case based on your comments). In that case no library is needed, you can simply use:
gcc -o test test.c iab202_graphics.c
and that will compile both those translation units then link them together.

Including c files leads to undefined references

When I include c files, I start to get undefined references to other functions. Then, I have to start including the c files that contain the functions. How do I get around this? The undefined references are referenced in the c files that I include, but since I am not actually including those files, I get undefined references.
Generally one includes ".h" files, not ".c" files.
If you call a function declared in a .h file, it is not sufficient to compile the starting C file to get a complete program -- you also need to link in the object files associated with the code that implements the declared functions. These might be in a library, in which case you need to link with that library.
You need to either compile all the files at once (gcc *.c) or compile each .c file into a separate object file and then link them all into the executable:
gcc -c main.c -o main.o
gcc -c helper.c -o helper.o
gcc -c other.c -o other.o
gcc *.o -o main
And within each .c file you should only ever include .h files.
What do you mean by including? Including via the #include preprocessor directive, or including as in adding them to your project.
You cannot get around the fact that all of the functions that are called (or, generally, externals symbols that are referenced) in your program either have to be included in that program, or have to exist in a library that is linked to the program, explicitly or implicitly.
Just keep adding the source files that are needed until all the references are resolved.
If you can't do that, then you may have some problem with the program or build. Either the program is incomplete (missing source files), corrupt (missing parts of source files), or you have included an inappropriate source file into the build (e.g. a source file which is needed when the program is compiled for Unix, but you're building for Windows) or incorrectly configured (so it is conditionally compiling some code for the wrong platform) or the program is simply not ported to your system (makes references to library functions you don't have).

Standard functions defined in header files or automatically linked?

When writing a basic c program.
#include <stdio.h>
main(){
printf("program");
}
Is the definition of printf in "stdio.h" or is the printf function automatically linked?
Usually, in stdio.h there's only the prototype; the definition should be inside a library that your object module is automatically linked against (the various msvcrt for VC++ on Windows, libcsomething for gcc on Linux).
By the way, it's <stdio.h>, not "stdio.h".
Usually they are automatically linked, but the compiler is allowed to implement them as it pleases (even by compiler magic).
The #include is still necessary, because it brings the standard functions into scope.
Stricto sensu, the compiler and the linker are different things (and I am not sure that the C standard speaks of compilation & linking, it more abstractly speaks of translation and implementation issues).
For instance, on Linux, you often use gcc to translate your hello.c source file, and gcc is a "driving program" which runs the compiler cc1, the assembler as, the linker ld etc.
On Linux, the <stdio.h> header is an ordinary file. Run gcc -v -Wall -H hello.c -o hello to understand what is happening. The -v option asks gcc to show you the actual programs (cc1 and others) that are used. The -Wall flag asks for all warnings (don't ignore them!). The -H flag asks the compiler to show you the header files which are included.
The header file /usr/include/stdio.h is #include-ing itself other headers. At some point, the declaration of printf is seen, and the compiler parses it and adjust its state accordingly.
Later, the gcc command would run the linker ld and ask it to link the standard C library (on my system /usr/lib/x86_64-linux-gnu/libc.so). This library contains the [object] code of printf
I am not sure to understand your question. Reading wikipedia's page about compilers, linkers, linux kernel, system calls should be useful.
You should not want gcc to link automagically your own additional libraries. That would be confusing. (but if you really wanted to do that with GCC, read about GCC specs file)

Linking with GCC and -lm doesn't define ceil() on Ubuntu

I am currently using GCC to compile and I need to use <math.h>.
The problem is that it won't recognize the library.
I have also tried -lm and nothing.
The function I tried to use was ceil() and I get the following error:
: undefined reference to `ceil'
collect2: ld returned 1 exit status
I am using the latest Ubuntu and math.h is there.
I tried to use -lm on a different computer, and it worked perfectly.
How can I solve this problem?
I did include <math.h>. Also, the command I used was:
gcc -lm -o fb file.c
Take this code and put it in a file ceil.c:
#include <math.h>
#include <stdio.h>
int main(void)
{
printf("%f\n", ceil(1.2));
return 0;
}
Compile it with:
$ gcc -o ceil ceil.c
$ gcc -o ceil ceil.c -lm
One of those two should work. If neither works, show the complete error message for each compilation. Note that -lm appears after the name of the source file (or the object file if you compile the source to object before linking).
Notes:
A modern compiler might well optimize the code to pass 2.0 directly to printf() without calling ceil() at all at runtime, so there'd be no need for the maths library at all.
Rule of Thumb: list object files and source files on the command line before the libraries. This answer shows that in use: the -lm comes after the source file ceil.c. If you're building with make etc, then you typically use ceil.o on the command line (along with other object files); normally, you should list all the object files before any of the libraries.
There are occasionally exceptions to the rule of thumb, but they are rare and would be documented for the particular cases where the exception is expected/required. In the absence of explicit documentation to the contrary, apply the rule of thumb.
I just wanted to mention that Peter van der Linden's book Expert C Programming has a good treatment on this subject in chapter 5 Thinking of Linking.
Archives (static libraries) are acted upon differently than are shared objects (dynamic libraries). With dynamic libraries, all the library symbols go into the virtual address space of the output file, and all the symbols are available to all the other files in the link. In contrast, static linking only looks through the archive for the undefined symbols presently known to the loader at the time the archive is processed.
If you specify the math library (which is usually a static one) before your object files, then the linker won't add any symbols.
Try compiling like that:
gcc -Wall -g file.c -lm -o file
I had the same problem and it was solved using this command. Also if you installed your Ubuntu the same day you had the problem it might be an update problem.

Resources