flat assembler
Message board for the users of flat assembler.
Index
> High Level Languages > Rules for linking Fasm to g++ on AMD64 |
Author |
|
fpga 23 Sep 2009, 11:42
The asm file containing the function to be called
i.e. print_str_2.fasm Code: format ELF64 ;executable ;change ;format ELF executable ;entry start SYSCALL_EXIT equ 1 SYSCALL_WRITE equ 4 STDOUT equ 1 ESC equ 0x1b ;start: _print_str: ;change ; first clear the screen mov eax, SYSCALL_WRITE mov ebx, STDOUT mov ecx, clear_screen mov edx, clear_screen_size int 0x80 ; move cursor to (x:25, y:12) mov eax, SYSCALL_WRITE mov ebx, STDOUT mov ecx, move_cursor mov edx, move_cursor_size int 0x80 ; write the message mov eax, SYSCALL_WRITE mov ebx, STDOUT mov ecx, message mov edx, message_size int 0x80 ; exit from the program mov eax, SYSCALL_EXIT xor ebx, ebx int 0x80 ret ;change ie added clear_screen: db ESC, "[2J" clear_screen_size = $ - clear_screen move_cursor: db ESC, "[12;25H" move_cursor_size = $ - move_cursor message: db ESC, "[31m", ESC, "[5m", ESC, "[4m" ; red, blink on, underline on db "Programming linux is easy", 0xa db ESC, "[25m", ESC, "[24m" ; blink off, underline off message_size = $ - message The c++ file that calls the asm function i.e. call_asm.cpp Code: #include "iostream" using namespace std; extern "C" void print_str(); int main(){ cout << "hi" << endl; print_str(); return 0; } my compiling shell script Code: #!/bin/sh ./fasm print_str_2.fasm print_str_2.o g++ -c call_asm.cpp g++ -o blob call_asm.o print_str_2.o ./blob rm blob and the error message that I get Code: flat assembler version 1.68 (16384 kilobytes memory) 2 passes, 669 bytes. call_asm.o: In function `main': call_asm.cpp.text+0x73): undefined reference to `print_str()' collect2: ld returned 1 exit status run.sh: 7: ./blob: not found rm: cannot remove `blob': No such file or directory |
|||
23 Sep 2009, 11:42 |
|
revolution 23 Sep 2009, 12:24
What is g++?
|
|||
23 Sep 2009, 12:24 |
|
fpga 23 Sep 2009, 12:51
It's gcc's c++ compiler
|
|||
23 Sep 2009, 12:51 |
|
revolution 23 Sep 2009, 12:56
I would expect you need to export the function names. Maybe ...
Code: public _print_str as '_print_str@0' |
|||
23 Sep 2009, 12:56 |
|
fpga 23 Sep 2009, 13:07
revolution
Thanks for trying. I put it as line 2 in print_str_2.fasm and got the same error. |
|||
23 Sep 2009, 13:07 |
|
revolution 23 Sep 2009, 13:09
It is probably something to do with name mangling in g++. How does g++ mangle the function names? You need to match the C name mangling in the public directive.
|
|||
23 Sep 2009, 13:09 |
|
MazeGen 23 Sep 2009, 14:47
Compile the call_asm.cpp file and look into the object file what external symbol GCC expects.
|
|||
23 Sep 2009, 14:47 |
|
fpga 23 Sep 2009, 14:54
Sorry to lose the continuity. I had to pop out for a while.
Your comment on mangling seems correct. Before I went I tried it with gcc and got Code: flat assembler version 1.68 (16384 kilobytes memory) 2 passes, 706 bytes. call_asm.c:2: error: expected identifier or ‘(’ before string constant call_asm.o: In function `main': call_asm.c.text+0x14): undefined reference to `print_str' collect2: ld returned 1 exit status Here's what I did... Code: #include <stdio.h> extern "C" void print_str(); int main (void){ printf ("Hello, world!\n"); print_str(); return 0; } Code: format ELF64 ;executable ;change public _print_str as '_print_str@0' ;format ELF executable ;entry start SYSCALL_EXIT equ 1 SYSCALL_WRITE equ 4 STDOUT equ 1 ESC equ 0x1b ;start: _print_str: ;change ; first clear the screen mov eax, SYSCALL_WRITE mov ebx, STDOUT mov ecx, clear_screen mov edx, clear_screen_size int 0x80 ; move cursor to (x:25, y:12) mov eax, SYSCALL_WRITE mov ebx, STDOUT mov ecx, move_cursor mov edx, move_cursor_size int 0x80 ; write the message mov eax, SYSCALL_WRITE mov ebx, STDOUT mov ecx, message mov edx, message_size int 0x80 ; exit from the program mov eax, SYSCALL_EXIT xor ebx, ebx int 0x80 ret ;change ie added clear_screen: db ESC, "[2J" clear_screen_size = $ - clear_screen move_cursor: db ESC, "[12;25H" move_cursor_size = $ - move_cursor message: db ESC, "[31m", ESC, "[5m", ESC, "[4m" ; red, blink on, underline on db "Programming linux is easy", 0xa db ESC, "[25m", ESC, "[24m" ; blink off, underline off message_size = $ - message Code: #!/bin/sh ./fasm print_str_2.fasm print_str_2.o gcc -c call_asm.c gcc -o blob call_asm.o print_str_2.o ./blob rm blob # Exit with successful status exit 0 |
|||
23 Sep 2009, 14:54 |
|
fpga 23 Sep 2009, 15:18
objdump -Dslx call_asm.o gives me the following.
I can see print_str in two places but am not sure what else this is telling me about the problem Code: call_asm.o: file format elf64-x86-64 call_asm.o architecture: i386:x86-64, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x0000000000000000 Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000001f 0000000000000000 0000000000000000 00000040 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 0000000000000000 0000000000000000 00000060 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 0000000000000000 0000000000000000 00000060 2**2 ALLOC 3 .rodata 0000000e 0000000000000000 0000000000000000 00000060 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .eh_frame 00000038 0000000000000000 0000000000000000 00000070 2**3 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA 5 .comment 00000024 0000000000000000 0000000000000000 000000a8 2**0 CONTENTS, READONLY 6 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000cc 2**0 CONTENTS, READONLY SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 call_asm.c 0000000000000000 l d .text 0000000000000000 .text 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 l d .bss 0000000000000000 .bss 0000000000000000 l d .rodata 0000000000000000 .rodata 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 g F .text 000000000000001f main 0000000000000000 *UND* 0000000000000000 puts 0000000000000000 *UND* 0000000000000000 print_str <== here Contents of section .text: 0000 554889e5 bf000000 00e80000 0000b800 UH.............. 0010 000000e8 00000000 b8000000 00c9c3 ............... Contents of section .rodata: 0000 48656c6c 6f2c2077 6f726c64 2100 Hello, world!. Contents of section .eh_frame: 0000 14000000 00000000 017a5200 01781001 .........zR..x.. 0010 030c0708 90010000 1c000000 1c000000 ................ 0020 00000000 1f000000 00410e10 8602430d .........A....C. 0030 06000000 00000000 ........ Contents of section .comment: 0000 00474343 3a202855 62756e74 7520342e .GCC: (Ubuntu 4. 0010 332e332d 35756275 6e747534 2920342e 3.3-5ubuntu4) 4. 0020 332e3300 3.3. Disassembly of section .text: 0000000000000000 <main>: main(): 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: bf 00 00 00 00 mov $0x0,%edi 5: R_X86_64_32 .rodata 9: e8 00 00 00 00 callq e <main+0xe> a: R_X86_64_PC32 puts-0x4 e: b8 00 00 00 00 mov $0x0,%eax 13: e8 00 00 00 00 callq 18 <main+0x18> 14: R_X86_64_PC32 print_str-0x4 <=========here 18: b8 00 00 00 00 mov $0x0,%eax 1d: c9 leaveq 1e: c3 retq Disassembly of section .rodata: 0000000000000000 <.rodata>: 0: 48 rex.W 1: 65 gs 2: 6c insb (%dx),%es%rdi) 3: 6c insb (%dx),%es%rdi) 4: 6f outsl %ds%rsi),(%dx) 5: 2c 20 sub $0x20,%al 7: 77 6f ja 78 <main+0x78> 9: 72 6c jb 77 <main+0x77> b: 64 21 00 and %eax,%fs%rax) Disassembly of section .eh_frame: 0000000000000000 <.eh_frame>: 0: 14 00 adc $0x0,%al 2: 00 00 add %al,(%rax) 4: 00 00 add %al,(%rax) 6: 00 00 add %al,(%rax) 8: 01 7a 52 add %edi,0x52(%rdx) b: 00 01 add %al,(%rcx) d: 78 10 js 1f <.eh_frame+0x1f> f: 01 03 add %eax,(%rbx) 11: 0c 07 or $0x7,%al 13: 08 90 01 00 00 1c or %dl,0x1c000001(%rax) 19: 00 00 add %al,(%rax) 1b: 00 1c 00 add %bl,(%rax,%rax,1) 1e: 00 00 add %al,(%rax) 20: 00 00 add %al,(%rax) 20: R_X86_64_32 .text 22: 00 00 add %al,(%rax) 24: 1f (bad) 25: 00 00 add %al,(%rax) 27: 00 00 add %al,(%rax) 29: 41 0e rex.B (bad) 2b: 10 86 02 43 0d 06 adc %al,0x60d4302(%rsi) 31: 00 00 add %al,(%rax) 33: 00 00 add %al,(%rax) 35: 00 00 add %al,(%rax) ... Disassembly of section .comment: 0000000000000000 <.comment>: 0: 00 47 43 add %al,0x43(%rdi) 3: 43 3a 20 rex.XB cmp (%r8),%spl 6: 28 55 62 sub %dl,0x62(%rbp) 9: 75 6e jne 79 <main+0x79> b: 74 75 je 82 <main+0x82> d: 20 34 2e and %dh,(%rsi,%rbp,1) 10: 33 2e xor (%rsi),%ebp 12: 33 2d 35 75 62 75 xor 0x75627535(%rip),%ebp # 7562754d <main+0x7562754d> 18: 6e outsb %ds%rsi),(%dx) 19: 74 75 je 90 <main+0x90> 1b: 34 29 xor $0x29,%al 1d: 20 34 2e and %dh,(%rsi,%rbp,1) 20: 33 2e xor (%rsi),%ebp 22: 33 00 xor (%rax),%eax |
|||
23 Sep 2009, 15:18 |
|
fpga 23 Sep 2009, 15:22
Here's the dump for print_str_2.o
Code: print_str_2.o: file format elf64-x86-64 print_str_2.o architecture: i386:x86-64, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x0000000000000000 Sections: Idx Name Size VMA LMA File off Algn 0 .flat 00000089 0000000000000000 0000000000000000 00000040 2**3 CONTENTS, ALLOC, LOAD, RELOC, CODE SYMBOL TABLE: 0000000000000000 l d .flat 0000000000000000 .flat 0000000000000000 g F .flat 0000000000000000 _print_str@0 Contents of section .flat: 0000 b8040000 00bb0100 0000b94c 000000ba ...........L.... 0010 04000000 cd80b804 000000bb 01000000 ................ 0020 b9500000 00ba0800 0000cd80 b8040000 .P.............. 0030 00bb0100 0000b958 000000ba 31000000 .......X....1... 0040 cd80b801 00000031 dbcd80c3 1b5b324a .......1.....[2J 0050 1b5b3132 3b323548 1b5b3331 6d1b5b35 .[12;25H.[31m.[5 0060 6d1b5b34 6d50726f 6772616d 6d696e67 m.[4mProgramming 0070 206c696e 75782069 73206561 73790a1b linux is easy.. 0080 5b32356d 1b5b3234 6d [25m.[24m Disassembly of section .flat: 0000000000000000 <_print_str@0>: _print_str@0(): 0: b8 04 00 00 00 mov $0x4,%eax 5: bb 01 00 00 00 mov $0x1,%ebx a: b9 4c 00 00 00 mov $0x4c,%ecx b: R_X86_64_32S .flat f: ba 04 00 00 00 mov $0x4,%edx 14: cd 80 int $0x80 16: b8 04 00 00 00 mov $0x4,%eax 1b: bb 01 00 00 00 mov $0x1,%ebx 20: b9 50 00 00 00 mov $0x50,%ecx 21: R_X86_64_32S .flat 25: ba 08 00 00 00 mov $0x8,%edx 2a: cd 80 int $0x80 2c: b8 04 00 00 00 mov $0x4,%eax 31: bb 01 00 00 00 mov $0x1,%ebx 36: b9 58 00 00 00 mov $0x58,%ecx 37: R_X86_64_32S .flat 3b: ba 31 00 00 00 mov $0x31,%edx 40: cd 80 int $0x80 42: b8 01 00 00 00 mov $0x1,%eax 47: 31 db xor %ebx,%ebx 49: cd 80 int $0x80 4b: c3 retq 4c: 1b 5b 32 sbb 0x32(%rbx),%ebx 4f: 4a 1b 5b 31 rex.WX sbb 0x31(%rbx),%rbx 53: 32 3b xor (%rbx),%bh 55: 32 35 48 1b 5b 33 xor 0x335b1b48(%rip),%dh # 335b1ba3 <_print_str@0+0x335b1ba3> 5b: 31 6d 1b xor %ebp,0x1b(%rbp) 5e: 5b pop %rbx 5f: 35 6d 1b 5b 34 xor $0x345b1b6d,%eax 64: 6d insl (%dx),%es%rdi) 65: 50 push %rax 66: 72 6f jb d7 <_print_str@0+0xd7> 68: 67 72 61 addr32 jb cc <_print_str@0+0xcc> 6b: 6d insl (%dx),%es%rdi) 6c: 6d insl (%dx),%es%rdi) 6d: 69 6e 67 20 6c 69 6e imul $0x6e696c20,0x67(%rsi),%ebp 74: 75 78 jne ee <_print_str@0+0xee> 76: 20 69 73 and %ch,0x73(%rcx) 79: 20 65 61 and %ah,0x61(%rbp) 7c: 73 79 jae f7 <_print_str@0+0xf7> 7e: 0a 1b or (%rbx),%bl 80: 5b pop %rbx 81: 32 35 6d 1b 5b 32 xor 0x325b1b6d(%rip),%dh # 325b1bf4 <_print_str@0+0x325b1bf4> 87: 34 6d xor $0x6d,%al |
|||
23 Sep 2009, 15:22 |
|
MazeGen 23 Sep 2009, 16:23
I'm Windows guy so can't try it, however, the puts function is declared as 'puts'. And it expects also 'print_str'. Doesn't this work?
Code: public _print_str as 'print_str' If not, try to ask on a GCC forum how it handles external symbols. |
|||
23 Sep 2009, 16:23 |
|
fpga 23 Sep 2009, 16:53
No problem. Thx for trying.
I've had a thread on codeguru's non-ms c++ forum since last night. It's normally very good but on this one I've had 0 responses. I think I read in the notes that public is for coff output and this is ELF64. I'll give it a go though. Despite looking last night and all of today I've failed to find a single working example of g++ calling Fasm. As both are very popular this seems quite strange and suggests that the two don't mix. My best bet therefore seems in-line GAS. Shame cos I really like the idea of Fasm. |
|||
23 Sep 2009, 16:53 |
|
LocoDelAssembly 23 Sep 2009, 18:33
fpga, from your latest fasm code I changed this:
Code: public _print_str as 'print_str' ; Changed string Then, I proceeded this way: Code: loco@athlon64:~/Desktop/linktest$ cat call_asm.cpp #include "iostream" using namespace std; extern "C" void print_str(); int main(){ cout << "hi" << endl; print_str(); return 0; } loco@athlon64:~/Desktop/linktest$ fasm print_str.fasm flat assembler version 1.69.03 (16384 kilobytes memory) 2 passes, 703 bytes. loco@athlon64:~/Desktop/linktest$ g++ -c call_asm.cpp loco@athlon64:~/Desktop/linktest$ g++ -o blob call_asm.o print_str.o loco@athlon64:~/Desktop/linktest$ uname -a Linux athlon64 2.6.28-15-generic #49-Ubuntu SMP Tue Aug 18 19:25:34 UTC 2009 x86_64 GNU/Linux The results of executing it are attached. (The font changed to red when I executed the code, it was previously black) [edit]Please not that "public print_str as 'print_str'" would also be valid but I haven't used it because that would required to change more lines (the line with "_print_str:" to "print_str:"). For linking what matters is the name in the quoted string. "public print_str" is equivalent to "public print_str as 'print_str'".
|
||||||||||
23 Sep 2009, 18:33 |
|
fpga 23 Sep 2009, 19:06
LocoDelAssembly
It took about a minute to get in-line GAS working in g++ and after my difficulty documented above I thought GAS was the way to go. You've just changed that and I'm very pleased about that. Thankyou very much for your time and trouble and to MazeGen and revolution. |
|||
23 Sep 2009, 19:06 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.