Error binary output format does not support external references

I am trying to compile an Assembly file to object file. This assembly file calls a c function. But i encounter this error: binary output format does not support external references I call the c fu...

I am trying to compile an Assembly file to object file. This assembly file calls a c function. But i encounter this error: binary output format does not support external references

I call the c function in line 17 of the assembly file

I try to compile it with this command:

cpu/interrupt.o: cpu/interrupt.asm
        nasm $< -f bin -o $@

how can i fix this problem

[extern isr_handler]

; Common ISR code
isr_common_stub:
    ; 1. Save CPU state
    pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
    mov ax, ds ; Lower 16-bits of eax = ds.
    push eax ; save the data segment descriptor
    mov ax, 0x10  ; kernel data segment descriptor
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    ; 2. Call C handler
    call isr_handler

    ; 3. Restore state
    pop eax 
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    popa
    add esp, 8 ; Cleans up the pushed error code and pushed ISR number
    sti
    iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP

; We don't get information about which interrupt was caller
; when the handler is run, so we will need to have a different handler
; for every interrupt.
; Furthermore, some interrupts push an error code onto the stack but others
; don't, so we will push a dummy error code for those which don't, so that
; we have a consistent stack for all of them.

; First make the ISRs global
global isr0
global isr1
global isr2
global isr3
global isr4
global isr5
global isr6
global isr7
global isr8
global isr9
global isr10
global isr11
global isr12
global isr13
global isr14
global isr15
global isr16
global isr17
global isr18
global isr19
global isr20
global isr21
global isr22
global isr23
global isr24
global isr25
global isr26
global isr27
global isr28
global isr29
global isr30
global isr31

When I’m running syntastic, I always see the NASM error,

binary output format does not support external references

This is because I’m assembling with nasm -f elf64. How do I instruct syntastic to test the syntax with -f elf64? Unfortunately, it doesn’t seem like I can skirt this issue with an in-file directive.

asked Oct 1, 2018 at 22:01

Evan Carroll's user avatar

2

I got this done with,

let g:syntastic_nasm_nasm_args = '-f elf64'

Thanks to lcd047 who referenced me in the comments to :h syntastic-config-makeprg

answered Oct 1, 2018 at 22:25

Evan Carroll's user avatar


Recommended Answers

what is main.bin? I never heard of linking a *.bin file with *.o files.

>> Since I can’t use nasm to make binary files with EXTERN’s
And why not? Its the linker that resolves the externs, not the assembler.

Jump to Post

According to nasm documentation PDF the EXTERN keyword should work. Maybe you should read it more carefully — you do have that documentation don’t you?

Jump to Post

>>I just want to link with the procedures I use in my source and not the entire file
does that mean you don’t want everything that is in procs.o? The linker will give you everything in a *.o file whethere used or not. Some linkers are however smarter and will …

Jump to Post

All 10 Replies

Member Avatar


Ancient Dragon

5,243



Achieved Level 70



Team Colleague



Featured Poster


15 Years Ago

what is main.bin? I never heard of linking a *.bin file with *.o files.

>> Since I can’t use nasm to make binary files with EXTERN’s
And why not? Its the linker that resolves the externs, not the assembler.

Member Avatar

15 Years Ago

Because if I try to assembly a file that has extern’s using nasm with flat binary output it says «error: binary output format does not support external references». And main.bin is supposed to be the output file name.

Member Avatar


Ancient Dragon

5,243



Achieved Level 70



Team Colleague



Featured Poster


15 Years Ago

According to nasm documentation PDF the EXTERN keyword should work. Maybe you should read it more carefully — you do have that documentation don’t you?

Member Avatar

15 Years Ago

The documentation was the first thing I checked. It says in section 5.4 «Not every object-file
format can support external variables: the bin format cannot». Plus you can only specify one input file with nasm so it couldn’t do what I want anyway…

Member Avatar


Ancient Dragon

5,243



Achieved Level 70



Team Colleague



Featured Poster


15 Years Ago

>>I just want to link with the procedures I use in my source and not the entire file
does that mean you don’t want everything that is in procs.o? The linker will give you everything in a *.o file whethere used or not. Some linkers are however smarter and will toss out unused code. I suspect your linker is not one of them.

Member Avatar

15 Years Ago

Ok sorry i’m too used too using gui’s that do all the compiling and linking for me… Do I need to make my procedures into a library file to do this?? If so can you tell me how to make a library file out of the procs.o file?

Thanks again

Member Avatar


Ancient Dragon

5,243



Achieved Level 70



Team Colleague



Featured Poster


15 Years Ago

Yes, create a library and split that procs source file into as many files as there are functions in it then compile each separately into its own *.o file then put all the *.o files into the library.

Member Avatar

15 Years Ago

Ah that makes sense.

One more thing that’s bothering me… Like I said in my first post ld is making the output file over 4kb when it should be much smaller. What kind of information is being added to the output and how can I get rid of it?

Member Avatar


Ancient Dragon

5,243



Achieved Level 70



Team Colleague



Featured Poster


15 Years Ago

>>What kind of information is being added to the output and how can I get rid of it?
It adds all the code that’s in procs.o and main.o. To my knowledge it doesn’t add any other code like compilers for other languages do. You would have to load the bin file into a binary editor such as debug.exe in MS-Windows to find out for sure.

Member Avatar

15 Years Ago

I just used a binary compare program called Bcf and it appears ld isn’t making raw binary afterall because the ld output file starts with ‘MZ’ and then says something about a stubb program. Guess i’ll have to read up on ld some more to see what i’m doing wrong.

Thank you!


Reply to this topic

Be a part of the DaniWeb community

We’re a friendly, industry-focused community of developers, IT pros, digital marketers,
and technology enthusiasts meeting, networking, learning, and sharing knowledge.

Er.. ok so I’m making a small kernel in NASM. Everything went ok till I got till the compilation stage. I’m using an extremely simple bootloader (much simpler than GRUB) that just sets up protected mode and loads the kernel, so I didn’t expect any problems. NASM keeps saying «error: binary output format does not support external references.» But that’s bull because I’ve not specified binary output format!

kernel.asm:

[bits 32] ; hey, we're in Protected Mode

[global start]
[extern _kernel_main] ; always add a "_" in front of a C function to call it

start:
  call _kernel_main
  jmp $ ; halt

kernel.c:

Can someone please help??

What command line do you use to build your kernel.asm?

nasm -o kernel.o c:devOSkernel.asm

There you go — NASM defaults to binary format. I guess by the «.o» that you want ELF format, so you need to use «nasm -f elf …».

I am trying to compile an Assembly file to object file. This assembly file calls a c function. But i encounter this error: binary output format does not support external references

I call the c function in line 17 of the assembly file

I try to compile it with this command:

cpu/interrupt.o: cpu/interrupt.asm
        nasm $< -f bin -o [email protected]

how can i fix this problem

[extern isr_handler]

; Common ISR code
isr_common_stub:
    ; 1. Save CPU state
    pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
    mov ax, ds ; Lower 16-bits of eax = ds.
    push eax ; save the data segment descriptor
    mov ax, 0x10  ; kernel data segment descriptor
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    ; 2. Call C handler
    call isr_handler

    ; 3. Restore state
    pop eax 
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    popa
    add esp, 8 ; Cleans up the pushed error code and pushed ISR number
    sti
    iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP

; We don't get information about which interrupt was caller
; when the handler is run, so we will need to have a different handler
; for every interrupt.
; Furthermore, some interrupts push an error code onto the stack but others
; don't, so we will push a dummy error code for those which don't, so that
; we have a consistent stack for all of them.

; First make the ISRs global
global isr0
global isr1
global isr2
global isr3
global isr4
global isr5
global isr6
global isr7
global isr8
global isr9
global isr10
global isr11
global isr12
global isr13
global isr14
global isr15
global isr16
global isr17
global isr18
global isr19
global isr20
global isr21
global isr22
global isr23
global isr24
global isr25
global isr26
global isr27
global isr28
global isr29
global isr30
global isr31

So, when I try to compile my code

section .boot
bits 16
global boot
boot:
mov ax, 0x2401
int 0x15

mov ax, 0x3
int 0x10

mov [disk],dl

mov ah, 0x2    ;read sectors
mov al, 6      ;sectors to read
mov ch, 0      ;cylinder idx
mov dh, 0      ;head idx
mov cl, 2      ;sector idx
mov dl, [disk] ;disk idx
mov bx, copy_target;target pointer
int 0x13
cli
lgdt [gdt_pointer]
mov eax, cr0
or eax,0x1
mov cr0, eax
mov ax, DATA_SEG
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp CODE_SEG:boot2
gdt_start:
dq 0x0
gdt_code:
dw 0xFFFF
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data:
dw 0xFFFF
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:
gdt_pointer:
dw gdt_end - gdt_start
dd gdt_start
disk:
db 0x0
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

times 510 - ($-$$) db 0
dw 0xaa55
copy_target:
bits 32
hello: db "Hello more than 512 bytes world!!",0
boot2:
mov esi,hello
mov ebx,0xb8000
.loop:
lodsb
or al,al
jz halt
or eax,0x0F00
mov word [ebx], ax
add ebx,2
jmp .loop
halt:
mov esp,kernel_stack_top
extern kmain
call kmain
cli
hlt

section .bss
align 4
kernel_stack_bottom: equ $
resb 16384 ; 16 KB
kernel_stack_top:

And whenver I compile with nasm -f bin boot.asm -o boot.bin, I get boot.asm:77: error: binary output format does not support external references
Anyway to fix this? Thanks, T.M.

Author Message

Post subject: C++ OS Programming

PostPosted: Sun Oct 22, 2006 12:33 am 

Offline
Member
Member



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

Do you have a knowledge of OS programming in C++(under Windows)?? Which compilers do you use and which commands do you use for compile. Please, place here a link to download them. thx

PS: Please excuse my formulation, because i am czechian.

Top

Profile  

Mike

Post subject: Re: C++ OS Programming

PostPosted: Sun Oct 22, 2006 12:59 am 



Joined: Tue Oct 17, 2006 7:57 pm
Posts: 25

I’m writing my OS in C++ in Microsoft Visual Studio 2005. (With FASM for the bootloader and protected-mode-entry stub) Check out «Visual C» on the wiki which details some of the issues I faced.

> PS: Please excuse my formulation, because i am czechian.

Cool! I am half-Czech… but unfortunately all I know of the language are the numbers 1-10, «good day», and «beer».

Mike

Top

Profile  

Cmaranec

Post subject: Which compiler

PostPosted: Sun Oct 22, 2006 1:08 am 



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

Which compilers and linkers do you use? If you use DJGPP please tell me what version. :roll:

Top

Profile  

Daedalus

Post subject:

PostPosted: Sun Oct 22, 2006 1:56 am 



Joined: Sun Oct 16, 2005 11:00 pm
Posts: 74
Location: Australia

DJGPP of any version seems to work fine for me.

Top

Profile  

Cmaranec

Post subject:

PostPosted: Sun Oct 22, 2006 2:34 am 



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

4 Daedalus: Which commands do you use to compile the kernel of your OS?? I am using:

Quote:

@ECHO OFF

echo Kompiluji kernel…

c:dev-cppbingcc -w -nostdlib -fno-builtin -ffreestanding -c -o kernel32.o kernel32.cpp

echo Kompiluji loader…

c:compilernasm -f aout Loader.asm -o Loader.o

echo Linkuji…

c:dev-cppbinld -o Kernel.bin Loader.o Kernel32.o

echo Proces dokoncen…

pause

And cmd.exe gave back: Loader.o: File not recognized: File format not recognized

What i do wrong?

Top

Profile  

inflater

Post subject:

PostPosted: Sun Oct 22, 2006 3:34 am 



Joined: Thu Sep 28, 2006 10:32 am
Posts: 1309
Location: Slovakia

Try this:

Code:

echo Kompilujem loader…

c:compilernasm -f bin Loader.asm -o Loader.o

echo Linkujem…

c:dev-cppbinld -oformat BINARY -o Kernel.bin Loader.o Kernel32.o

I am full Slovak, full Czech, «sort of a English’er» and «Ich spreche auch Deutsch, bitte !» :D

Slovensko pozdravuje Česko !

inflater

Top

Profile  

Cmaranec

Post subject: eh

PostPosted: Sun Oct 22, 2006 3:57 am 



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

Now, it throw

Quote:

Kompiluji kernel…
Kompiluji loader…
Loader.asm:6: error: binary output format does not support external references
Linkuji…
c:dev-cppbinld: target BINARY not found
Proces dokoncen…
Pokračujte stisknutím libovolné klávesy…

Česko zdraví Slovensko! :D

Top

Profile  

Combuster

Post subject:

PostPosted: Sun Oct 22, 2006 7:56 am 



Joined: Wed Oct 18, 2006 3:45 am
Posts: 9301
Location: On the balcony, where I can actually keep 1½m distance

Uner windows you have three standard choices: GCC (cross-compiler, perhaps) MSVC and Watcom

I personally use the GCC cross-compiler, but you should check the wiki on how to use each of them, since the compilers, linkers and assemblers are generally not interoperable by default.

On another note, nasm generates binary output in this construction, not object files.

you should use

Code:

nasm -f elf -o loader.o loader.asm

change «elf» with a different format to change the output. you may want to try «coff» if you use something else than gnu ld

(try «nasm -hf» to see what nasm can give you)

Something similar goes for the ld, where the parameter should probably read «—otarget binary», case sensitive.


_________________
«Certainly avoid yourself. He is a newbie and might not realize it. You’ll hate his code deeply a few years down the road.» — Sortie
[ My OS ] [ VDisk/SFS ]

Top

Profile  

Cmaranec

Post subject: errr

PostPosted: Sun Oct 22, 2006 8:24 am 



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

In linking procces is something wrong:

Quote:

Kompiluji kernel…
Kompiluji loader…
Linkuji…
Kernel32.o(.text+0xd):kernel32.cpp: undefined reference to `std::string::size()
const’
Kernel32.o(.text+0x60):kernel32.cpp: undefined reference to `std::string::operat
or[](unsigned int) const’
Kernel32.o(.text+0x9f):kernel32.cpp: undefined reference to `std::string::operat
or[](unsigned int) const’
Kernel32.o(.text+0xce):kernel32.cpp: undefined reference to `std::string::operat
or[](unsigned int) const’
Kernel32.o(.text+0x121):kernel32.cpp: undefined reference to `_alloca’
Kernel32.o(.text+0x126):kernel32.cpp: undefined reference to `__main’
Kernel32.o(.text+0x135):kernel32.cpp: undefined reference to `std::cout’
Kernel32.o(.text+0x13a):kernel32.cpp: undefined reference to `std::basic_ostream
<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::
basic_ostream<char, std::char_traits<char> >&, char const*)’
Kernel32.o(.text+0x163):kernel32.cpp: undefined reference to `std::ios_base::Ini
t::Init()’
Kernel32.o(.text+0x17e):kernel32.cpp: undefined reference to `std::ios_base::Ini
t::~Init()’
Proces dokoncen…
Pokračujte stisknutím libovolné klávesy…

I use «nasm -f elf Loader.asm -o Loader.o».

Loader.o is succesfully compiled and linked, but in Kernel32.o is bug…

Last edited by Cmaranec on Sun Oct 22, 2006 8:34 am, edited 1 time in total.

Top

Profile  

Cmaranec

Post subject: linker script

PostPosted: Sun Oct 22, 2006 8:30 am 



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

I have a linker script from wiki. When i used the old classic linker script, it wrote «PE operations on non PE file». I use script from wiki.

Top

Profile  

bluecode

Post subject:

PostPosted: Sun Oct 22, 2006 9:14 am 



Joined: Wed Nov 17, 2004 12:00 am
Posts: 202
Location: Germany

You have to build a crosscompiler under windows if you want to use the elf file format for your os. There is also an article on the wiki about that.

Top

Profile  

Cmaranec

Post subject: heh…

PostPosted: Sun Oct 22, 2006 10:01 am 



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

Can you (or anybody other) send me an example of your simple OS with .BAT file??? It will be better.

Top

Profile  

Pype.Clicker

Post subject:

PostPosted: Sun Oct 22, 2006 11:28 am 



Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away

it sounds like you’re missing the string class and COUT stuff to have your kernel running. You know you cannot simply reuse the standard library of your hosting OS, don’t you?


_________________
Image May the source be with you.

Top

Profile  

Cmaranec

Post subject: yes

PostPosted: Sun Oct 22, 2006 12:15 pm 



Joined: Sat Oct 21, 2006 1:07 pm
Posts: 45
Location: Czech Republic

Yes, i know. How i insert this classes to my kernel?

Top

Profile  

bluecode

Post subject:

PostPosted: Sun Oct 22, 2006 1:52 pm 



Joined: Wed Nov 17, 2004 12:00 am
Posts: 202
Location: Germany

Make your own std::string class or port an existing C++ library. I don’t recommend the later one at your stage, it’s just to much C++ runtime required (exception handling, RTTI).


_________________
lightOS

Top

Profile  

Ошибка в загрузчике: Помощь в сборке

Я пытаюсь создать простую операционную систему, но при компиляции загрузчика получаю ошибку:

error: binary output format does not support external references

Я знаю, что означает эта ошибка, но можно ли делать внешние ссылки при компиляции в бинарный формат? Вот мой полный код:

;Bootloader.s
[BITS 16]     
[ORG 0x7C00]
global loader
extern kmain

loader:
call kmain
times 510-($-$$) db 0
dw 0xAA55 

И мое ядро:

/*kernel.c*/
void kmain()
{
    unsigned char *vidmem = (unsigned char *) 0xb8000;
    int i
    for(i=1;i<=11;i+=2)
    {
        vidmem[i]=0x07;
    }
    vidmem[0]='H';
    vidmem[2]='e';
    vidmem[4],vidmem[6]='l';
    vidmem[8]='o';
    videmem[10]='!';
}

Как я скомпилировал:

nasm -o '/home/myusername/Cubed OS/Bootloader.o' '/home/myusername/Cubed OS/Bootloader.s'

У вас могут быть только внешние ссылки в форматах объектных файлов, которые можно связывать. Голый двоичный файл — нет, поэтому вы не можете сделать это напрямую.

(И вам нужно настроить стек, прежде чем вы сможете вызвать функцию C AFAIK.)

Я вижу три пути решения этой проблемы:

  • Используйте загрузчик с мультизагрузкой и запишите ядро ​​в виде ELF-образа. См. OSDev Голые кости для примера этого.
  • Пишите все на ассемблере. См. например Как написать простую операционную систему.
  • Напишите все это в C и используйте трюки компоновщика, чтобы выровнять вещи там, где они должны быть. Пример этого с набором инструментов GCC можно найти здесь: Реальный режим на C с помощью gcc: пишем загрузчик

ответ дан 20 авг.

Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками

assembly
operating-system
bootloader

or задайте свой вопрос.

Понравилась статья? Поделить с друзьями:
  • Error bin sh does not point to bash
  • Error asyncio task exception was never retrieved
  • Error assignment to expression with array type си
  • Error bgi graphics not supported under windows
  • Error assignment to cast is illegal lvalue casts are not supported