NASM - The Netwide Assembler

NASM Forum => Programming with NASM => Topic started by: maplesirop on March 13, 2013, 07:19:31 PM

Title: how do we print in assembly?
Post by: maplesirop on March 13, 2013, 07:19:31 PM
Code: [Select]
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'

Title: Re: how do we print in assembly?
Post by: maplesirop on March 13, 2013, 07:30:00 PM
Code: [Select]
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



Title: Re: how do we print in assembly?
Post by: maplesirop on March 13, 2013, 07:36:09 PM
Code: [Select]
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


Title: Re: how do we print in assembly?
Post by: Gerhard on March 13, 2013, 09:14:40 PM
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
Title: Re: how do we print in assembly?
Post by: maplesirop on March 13, 2013, 09:25:43 PM
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?
Title: Re: how do we print in assembly?
Post by: Keith Kanios on March 13, 2013, 10:57:16 PM
Perhaps gcc -m32 -o ex1 ex1.o will work?
Title: Re: how do we print in assembly?
Post by: Frank Kotler on March 13, 2013, 11:15:21 PM
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...
Code: [Select]
; 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

Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 12:01:36 PM
Thanks

Are these commands really needed though?

 -I/lib/ld-linux.so.2 -lc -m
Title: Re: how do we print in assembly?
Post by: Frank Kotler on March 14, 2013, 12:45:29 PM
"-m elf_i386" isn't needed on my (32-bit) machine.

Best,
Frank

Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 02:13:01 PM
ld: cannot find -l/lib/ld-linux.so.2

ld -o A3 A3.o -l/lib/ld-linux.so.2 -lc -m elf_i386
Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 02:16:05 PM
A3(.text+0x43): undefined reference to `printf'
Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 02:19:21 PM
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
Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 02:20:45 PM
Yeah... I don't know how I can compile this.
Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 02:27:29 PM
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...
Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 02:44:28 PM
Code: [Select]
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.

Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 02:55:58 PM
Code: [Select]
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.
Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 03:10:57 PM
/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
Title: Re: how do we print in assembly?
Post by: TightCoderEx on March 14, 2013, 03:14:35 PM
Here are a few Display (http://asm.sourceforge.net/intro/hello.html) strings examples
Title: Re: how do we print in assembly?
Post by: maplesirop on March 14, 2013, 03:23:02 PM
I want to print two digits integers.
Title: Re: how do we print in assembly?
Post by: Frank Kotler on March 14, 2013, 06:19:50 PM
It appears your system hasn't got the 32-bit libraries...
Code: [Select]
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?
Code: [Select]
; 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