I've started learning Assembly, and I have two files:
main.c
#include <stdio.h>
int assembly(void);
int main(void)
{
printf("Resultado: %d\n", assembly());
return 0;
}
and
assembly.asm
global assembly
assembly:
mov eax, 777
ret
So I used this command "nasm assembly.asm -f elf64" and it created the file "assembly.o". After that, I used another command "gcc -c main.c -o main.o" but it showed some errors on the shell:
What can I do?
Related
I have the following code with an inline assembly in C:
#include <stdlib.h>
#include <stdio.h>
__attribute__((noinline))
int *get_indecies(int *padding, int pad_size, int size, int alias_type);
int *get_indecies(int *padding, int pad_size, int size, int alias_type){
int *indecies = (int *)malloc(size*sizeof(int));
asm("dsb sy\n\t");
return indecies;
}
At the bottom I the inline is inserted...
When I produce the object code using (cross compilation for aarch64) I have the inline inserted:
.....
1f0: d5033f9f dsb sy
1f4: aa1f03e1 mov x1, xzr
......
when I link this binary with my main file using:
clang verification.c get_indecies.o -I "/home/[name]/gem5/include" -L "/home/[name]/gem5/util/m5/build/arm64/out" -lm5 -lc -O0 -static -target aarch64-linux-gnu -o verfication-base-m5
and then I do an object dump of this to check if the assembly instruction is present using:
aarch64-linux-gnu-objdump verification-base-m5 -S > assembly.s
The inline assembly does not exist.... Any ideas about what is happening in the linking stage that is removing this assembly instruction? The optimisation level is turned to 0 so I am not sure...
Thanks!
I re-ran the below line recently:
clang verification.c get_indecies.o -I "/home/[name]/gem5/include" -L "/home/[name]/gem5/util/m5/build/arm64/out" -lm5 -lc -O0 -static -target aarch64-linux-gnu -o verfication-base-m5
and then object dumped this and the inline assembly was present. Not sure what the bug was during the time but in my case it is resolved.
I tried to create a library and test it, but an error occurred.
error code:
./libasm.a: error adding symbols: Archive has no index; run ranlib to add one
collect2: error: ld returned 1 exit status
I compiled it like this.
nasm -f macho64 ft_strlen.s -o ft_strlen.o
ar rcs libasm.a ft_strlen.o
ranlib libasm.a
gcc main.c libasm.a
Below is the source file
;ft_strlen.s
segment .text
global ft_strlen
ft_strlen:
mov rax, 0
jmp count
count:
cmp BYTE [rdi + rax], 0
je exit
inc rax
jmp count
exit:
ret
/*main.c*/
#include <stdio.h>
int ft_strlen(char *str);
int main(void)
{
char *str = "hello world";
printf("%d \n", ft_strlen(str));
}
I am using ubuntu installed on wsl.
What am I doing wrong?
Generate object files for Linux-based operating system (or perhaps more correctly, and ELF64 system) with nasm -f elf64 ft_strlen.s -o ft_strlen.o
For more info nasm -hf to see all valid output formats for nasm -f
Small tip: ranlib command is not needed because ar s is already indexing the library.
i have this simple code that accepts numbers from the standard input and print them , i wrote this code on code blocks and it works .. now i want to run the same code on eclipse and i don't know how it's supposed to work ? also after that i run it on eclipse i need to run it on bash where i have a directory that includes tests and i nee to check my code with these tests but i can't figure how to compile this c program there !
this is this is the simple code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
int i;
int k;
int a;
printf("Enter size of input:\n");
scanf("%d",&x);
if (x<0){
printf("Invalid size\n");
return 0;
}
int *numbers=malloc(sizeof(int)*x);
printf("Enter numbers:\n");
for(i=0;i<x;++i){
scanf("%d",&numbers[i]);
}
for(k=0;k<x;++k)
{
a=numbers[k];
printf("The number %d is a power of 2 \n",a);
}
return 0;
}
also i am tried to compile this code on bash with this line :
-std=c99 -Wall -pedantic-errors -Werror -DNDEBUG main.c compiled.o
what am i doing wrong ?
Use the following command. Works like a charm in ubuntu bash. You can just input the values in the terminal, after running the program.
gcc main.c -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG -o main
Above a command generates a binary with the name main, Run the main file using following command.
./main
Then enter the your values.
To compile gcc main.c -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG -o main
to run from bash and accept arguments from a file named 'testcasefile' ;type following
main < (path to file)/testcasefile. 3 as for howv to run from eclipse refer to
https://stackoverflow.com/a/16921891/6721448
Let's start anew. Make a new directory for your project main inside project directory a directory for test case testcase
mkdir -p main main/testcase
now make test cases
Test case 1
2
3
4
compile main.c as follows
gcc - std=c99 -Wall -o main main.c
execute out put main with test case
./ main < testcase/testcase1
I wrote some code in nasm and I'm trying to implement it in a C program as a replacement of strlen through a shared library, but it doesn't work.
nasm code:
section .text
global strlen:function
strlen:
mov rax, 42
ret
C code:
#include <stdio.h>
size_t strlen(const char *s);
int main()
{
printf("%zu\n", strlen("foobar"));
return (0);
}
I compile the C program just using gcc without any arguments, and I create the shared library with the following commands:
nasm -f elf64 strlen.asm
gcc -shared -fPIC -o libasm.so strlen.o
Finally, I include the shared library:
export LD_PRELOAD=`pwd`/libasm.so
But it displays '6' where I expect it to display '42'.
I don't think the problem comes from my library, because I get segmentation fault when I execute the ls command with LD_PRELOAD.
I'm working on Ubuntu 16.04.
This is not related to nasm at all. A C equivalent of your strlen() function does not work either.
$ cat strlen.c
#include <stddef.h>
size_t strlen(const char *s)
{
return 43;
}
$ cat s.c
#include <stdio.h>
size_t strlen(const char *s);
int main()
{
printf("%zu\n", strlen("foobar"));
return 0;
}
$ make s
cc s.c -o s
$ gcc -shared -fPIC -o strlen.so strlen.c
$ LD_PRELOAD=$PWD/strlen.so ./s
6
What is happening here is that gcc is using its own built-in version of strlen() that cannot be overridden. If the C program that calls strlen() is recompiled to not use this built-in version of strlen(), then your shared library can override it.
$ rm s
$ make s CFLAGS=-fno-builtin-strlen
cc -fno-builtin-strlen s.c -o s
$ LD_PRELOAD=$PWD/strlen.so ./s
43
$ LD_PRELOAD=$PWD/libasm.so ./s
42
I have a small program that's made of an assembly function and a C function which calls it.
Now the program compiles and works perfectly on a UNIX system but when using the makefile in cygwin i get the following error:
gcc -m32 -g -c -o main.o main.c
gcc -g -m32 -o ass0 main.o myasm.o
main.o: In function main':
/cygdrive/c/ass0/main.c:15: undefined reference to_strToLeet'
collect2: error: ld returned 1 exit status
makefile:3: recipe for target 'ass0' failed
make: *** [ass0] Error 1
code of the main.c file :
#include <stdio.h>
# define MAX_LEN 100 // Maximal line size
extern int strToLeet (char*);
int main(void) {
char str_buf[MAX_LEN];
int str_len = 0;
printf("Enter a string: ");
fgets(str_buf, MAX_LEN, stdin); // Read user's command line string
str_len = strToLeet (str_buf); // Your assembly code function
printf("\nResult string:%s\nNumber of letters converted to Leet: %d\n",str_buf,str_len);
}
start of assembly code:
section .data ; data section, read-write
an: DD 0 ; this is a temporary var
section .text ; our code is always in the .text section
global strToLeet ; makes the function appear in global scope
extern printf ; tell linker that printf is defined elsewhere
strToLeet: ; functions are defined as labels
push ebp ; save Base Pointer (bp) original value
mov ebp, esp ; use base pointer to access stack contents
pushad ; push all variables onto stack
mov ecx, dword [ebp+8] ; get function argument
makefile code :
all: ass0
ass0: main.o myasm.o
gcc -g -m32 -o ass0 main.o myasm.o
main.o: main.c
gcc -m32 -g -c -o main.o main.c
myasm.o: myasm.s
nasm -g -f elf -l ass0list -o myasm.o myasm.s
help would be most appriciated
Solved by user 'tvin' -
Try to modify your prototype to become extern int strToLeet (char*) asm ("strToLeet"); – tivn