Author Topic: how do we print in assembly?  (Read 17026 times)

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
how do we print in assembly?
« 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'


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #1 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




Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #2 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



Offline Gerhard

  • Jr. Member
  • *
  • Posts: 51
Re: how do we print in assembly?
« Reply #3 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

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #4 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?

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: how do we print in assembly?
« Reply #5 on: March 13, 2013, 10:57:16 PM »
Perhaps gcc -m32 -o ex1 ex1.o will work?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how do we print in assembly?
« Reply #6 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


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #7 on: March 14, 2013, 12:01:36 PM »
Thanks

Are these commands really needed though?

 -I/lib/ld-linux.so.2 -lc -m

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: how do we print in assembly?
« Reply #8 on: March 14, 2013, 12:45:29 PM »
"-m elf_i386" isn't needed on my (32-bit) machine.

Best,
Frank


Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #9 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

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #10 on: March 14, 2013, 02:16:05 PM »
A3(.text+0x43): undefined reference to `printf'

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #11 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

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #12 on: March 14, 2013, 02:20:45 PM »
Yeah... I don't know how I can compile this.

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #13 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...

Offline maplesirop

  • Jr. Member
  • *
  • Posts: 60
Re: how do we print in assembly?
« Reply #14 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.