NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: maplesirop on March 13, 2013, 07:19:31 PM
-
segment .data
segment .bss
segment .text
extern _printf
global _start
_start:
mov ecx, 44
push ecx
call _printf
ret
mov eax, 4
mov ebx, 1
int 0x80
mov eax, 1
xor ebx, ebx
int 0x80
nasm -f elf ex1.asm
ld -o ex1 ex1.o
ld: warning: i386 architecture of input file `ex1.o' is incompatible with i386:x86-64 output
ex1.o: In function `_start':
ex1.asm:(.text+0x7): undefined reference to `_printf'
-
segment .data
segment .bss
segment .text
extern printf
global main
main:
mov ecx, 44
push ecx
call printf
ret
mov eax, 4
mov ebx, 1
int 0x80
mov eax, 1
xor ebx, ebx
int 0x80
nasm -f elf ex1.asm -o ex1.o
gcc -o ex1 ex1.o
/usr/bin/ld: warning: i386 architecture of input file `ex1.o' is incompatible with i386:x86-64 output
./ex1
Segmentation fault
-
segment .data
msg: db "value", 10, 0
segment .bss
segment .text
extern printf
global main
main:
push ebp
mov ebp, esp
mov eax, 4
push eax
push msg
call printf
add esp, 8
mov esp, ebp
pop ebp
ret
nasm -f elf ex1.asm -o ex1.o
gcc -o ex1 ex1.o
/usr/bin/ld: warning: i386 architecture of input file `ex1.o' is incompatible with i386:x86-64 output
./ex1
Segmentation fault
-
Hi maplesirop,
do you work under a 64 bit operating system? That won't work. You'll need the 32 bit compiler and linker.
Gerhard
-
thanks for your help.
ah... one of the program i made worked though... damn... is there a way to convert the code into 32bit assembly code?
-
Perhaps gcc -m32 -o ex1 ex1.o will work?
-
Well, the question isn't so much "how do we print in asm?" as "how do we print in my OS?"
You've got 32-bit code there, but ld and gcc on your (evidently) 64-bit system are expecting to build 64-bit code, by default. To tell ld we want 32-bit code, "-m elf_i386". On my old brain-dead ld, I get 32-bit code by default, but I need to tell it which dynamic linker (interpreter) to use. By default, it looks for /lib/ld-linux.so.1 - which does not exist on my system. This results in a "file not found" error message when I try to run my masterpiece - even though I can see it right there! Quite confusing, until someone gave me the clue to specify ...so.2. I have no idea what your ld will be looking for by default, or where to find what it really wants. In any case, we will need to tell ld "-lc" so it'll link against the C library... where it will find "printf".
To tell gcc we want 32-bit code, just "-m32". This is simpler, since gcc knows what to tell ld.
You may encounter another difficulty... apparently not all distros come with the 32-bit C libraries. There's an "apt-get" command to add 'em - "comb-libs" or something... I forget...
I'm surprised that you get as far as a segfault. I wouldn't expect the file to exist at all. Apparently that's just a "warning" about "incompatible with x86-64" and it goes ahead and builds... something. I can't imagine what, since "push eax" is invalid in 64 bit code (I understand).
The latest version of your code looks about right. You haven't got any "tokens" in your format string, so the number you push will be ignored, but you clean up the stack properly - I'd expect it to print "value" and exit cleanly. (haven't tried it) See if adding "-m32" to gcc's command line helps, or if that causes more complaints.
This "works for me" with command lines as given in the comments...
; nasm -f elf32 myprog.asm
; ld -o myprog myprog.o -I/lib/ld-linux.so.2 -lc -m elf_i386
global _start
extern printf
section .data
matrix dd 3, 6, 9,\
4, 8, 12,\
5, 15, 20
; note back-apostrophes!
fmt db `%u, %u, %u\n%u, %u. %u\n%u, %u, %u\n\0`
section .text
_start:
call print_matrix ; just to prove we can
mov eax, 1
xor ebx, ebx
int 0x80
;--------------------
;-------------------
print_matrix:
; these should probably be parameters...
mov ebx, matrix
mov ecx, 9
.top:
; push parameters, last first
dec ecx
js .end
push dword [ebx + ecx * 4]
jmp .top
.end:
push fmt ; format string pushed last
call printf
add esp, 4 * 10 ; caller cleans up stack!
ret ; just to prove stack is right
;-----------------------
I don't know if that'll help, or just create more confusion. Less source code than my last attempt to print a matrix, if nothing else! :)
Best,
Frank
-
Thanks
Are these commands really needed though?
-I/lib/ld-linux.so.2 -lc -m
-
"-m elf_i386" isn't needed on my (32-bit) machine.
Best,
Frank
-
ld: cannot find -l/lib/ld-linux.so.2
ld -o A3 A3.o -l/lib/ld-linux.so.2 -lc -m elf_i386
-
A3(.text+0x43): undefined reference to `printf'
-
nasm -f elf32 myprog.asm
ld -o myprog myprog.o -I/lib/ld-linux.so.2 -lc -m elf_i386
ld: skipping incompatible /usr/lib64/libc.so when searching for -lc
ld: skipping incompatible /usr/lib64/libc.a when searching for -lc
ld: cannot find -lc
-
Yeah... I don't know how I can compile this.
-
nasm -f elf ex1.asm -o ex1.o
gcc -o ex1 ex1.o -m elf_i386
/usr/bin/ld: skipping incompatible /nfs/encs/ArchDep/x86_64.linux26-RHEL5/pkg/gcc-4.1.2/root/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.1.2/libgcc.a when searching for -lgcc
/usr/bin/ld: skipping incompatible /encs/pkg/gcc-4.1.2/root/lib/gcc/x86_64-unknown-linux-gnu/4.1.2/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc
collect2: ld returned 1 exit status
great...
-
segment .data
segment .bss
segment .text
extern _printf
global _start
_start:
mov ecx, 44
mov eax, 4
mov ebx, 1
int 0x80
mov eax, 1
xor ebx, ebx
int 0x80
nasm -f elf32 exx.asm
ld -o exx exx.o -m elf_i386
./exx
does nothing...
Ok, can someone tell me how to do it without any external lib functions?
I want to print 44 on the screen.
-
segment .data
segment .bss
segment .text
extern _printf
global _start
_start:
mov ecx, 1
mov edx, ecx
add edx, 30h
mov ecx, edx
mov eax, 4
mov ebx, 1
int 0x80
mov eax, 1
xor ebx, ebx
int 0x80
This doesn't even work.
-
/usr/bin/ld: skipping incompatible /nfs/encs/ArchDep/x86_64.linux26-RHEL5/pkg/gcc-4.1.2/root/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.1.2/libgcc.a when searching for -lgcc
/usr/bin/ld: skipping incompatible /encs/pkg/gcc-4.1.2/root/lib/gcc/x86_64-unknown-linux-gnu/4.1.2/libgcc.a when searching for -lgcc
I get this when I write:
gcc -o exz exz.o -m elf_i386
and when i write this:
gcc -o exz exz.o
I get this:
/usr/bin/ld: warning: i386 architecture of input file `exz.o' is incompatible with i386:x86-64 output
-
Here are a few Display (http://asm.sourceforge.net/intro/hello.html) strings examples
-
I want to print two digits integers.
-
It appears your system hasn't got the 32-bit libraries...
apt-get install ia32-libs
Or, write yourself some 64-bit code. This is very different from 32-bit code! There are examples around...
Or, go back to 32-bit system calls... or 64-bit system calls. You've got my example of "print the matrix" (not very good, but it works). You'll have to tell ld "-melf_i386", but you won't be looking for libraries you don't have.
You wanna do just two digits?
; value in al
aam
add ax, 0x3030
xchg al, ah
mov [buffer[, ax
mov eax, 4
mov ebx, 1
mov ecx, buffer
mov edx, 2
int 0x80
(untested!)
Best,
Frank