无法在NASM中包含文件

时间:2013-08-06 10:07:58

标签: assembly nasm

我尝试使用

将文件包含到我的boot.asm文件中
%include "input.asm"

但每次我尝试编译它时都会收到错误消息,说nasm无法打开包含文件 input.inc与boot.asm位于同一目录中 我在这里和谷歌寻找答案,但没有人帮助过我。

是否有一种特殊的方式包含文件应该在包含之前编译/格式化?或者只是我对我的咆哮?

编辑:这是包含的代码:

mov ax, 0x07C0  ; set up segments
mov ds, ax    mov es, ax
mov si, welcome
call print_string
mov si, welcome2    
call print_string    
mov si, welcome4    
call print_string  
jmp .mainloop

%include 'input.asm'
mainloop:    ;loop here

input.asm:

 ; ================
 ; calls start here
 ; ================

 print_string:
   lodsb        ; grab a byte from SI

   or al, al  ; logical or AL by itself
   jz .done   ; if the result is zero, get out

   mov ah, 0x0E
   int 0x10      ; otherwise, print out the character!

   jmp print_string

 .done:
   ret

 get_string:
   xor cl, cl

 .loop:
   mov ah, 0
   int 0x16   ; wait for keypress

   cmp al, 0x08    ; backspace pressed?
   je .backspace   ; yes, handle it

   cmp al, 0x0D  ; enter pressed?
   je .done      ; yes, we're done

   cmp cl, 0x3F  ; 63 chars inputted?
   je .loop      ; yes, only let in backspace and enter

   mov ah, 0x0E
   int 0x10      ; print out character

   stosb  ; put character in buffer
   inc cl
   jmp .loop

 .backspace:
   cmp cl, 0    ; beginning of string?
   je .loop ; yes, ignore the key

   dec di
   mov byte [di], 0 ; delete character
   dec cl       ; decrement counter as well

   mov ah, 0x0E
   mov al, 0x08
   int 10h      ; backspace on the screen

   mov al, ' '
   int 10h      ; blank character out

   mov al, 0x08
   int 10h      ; backspace again

   jmp .loop    ; go to the main loop

 .done:
   mov al, 0    ; null terminator
   stosb

   mov ah, 0x0E
   mov al, 0x0D
   int 0x10
   mov al, 0x0A
   int 0x10     ; newline

   ret

 strcmp:
 .loop:
   mov al, [si]   ; grab a byte from SI
   mov bl, [di]   ; grab a byte from DI
   cmp al, bl     ; are they equal?
   jne .notequal  ; nope, we're done.



   cmp al, 0  ; are both bytes (they were equal before) null?
   je .done   ; yes, we're done.

   inc di     ; increment DI
   inc si     ; increment SI
   jmp .loop  ; loop!

 .notequal:
   clc  ; not equal, clear the carry flag
   ret

 .done:     
   stc  ; equal, set the carry flag
   call print_string
   ret

错误消息:

  

D:\ ASMT \ boot.asm:14:致命:无法打开包含文件`input.asm'

2 个答案:

答案 0 :(得分:8)

似乎NASM包含当前目录中的文件:

  

在当前目录中搜索包含文件(运行NASM时所在的目录,而不是NASM可执行文件的位置或源文件的位置),以及使用-i选项在NASM命令行上指定的任何目录。

如果您从NASM的另一个目录中执行D:\ASMT,则无法正常工作。

来源:http://www.nasm.us/doc/nasmdoc4.html#section-4.6.1

答案 1 :(得分:2)

NASM为您提供了将其他源文件包含到代码中的功能。实现此目的的方法是使用%include指令,如下所示:

%include "input.asm"

一个警告是,NASM假定所有文件都在当前工作目录内,例如运行NASM的目录。如果将文件传递到%include指令,并且该文件不能位于当前工作目录中,则NASM将返回以下错误:

fatal: unable to open include file

一种解决方案(已在接受的答案中给出)是使用-i选项在NASM命令行上指定任何其他引用的目录。例如,让我们假设一个名为“ print_string”的“ include”文件位于目录“ procedure_library”内,并且该目录为 not NASM“ launch”目录。在这种情况下,我们仅告诉NASM在哪里可以找到其他源文件,就像这样:

nasm -i/home/user/asmwork/procedure_library/ -f elf64 -g -F dwarf sourecode.asm

* -i和路径名之间的空格是允许的,并且是可选的)

这是维护项目的首选方式。但是,就击键而言,这是一个很长的命令。虽然,使用Makefile可以解决此问题。

n.b。 NASM不了解其运行的操作系统的文件命名约定;您作为-i选项的参数提供的字符串将完全按照编写的方式进行解析。因此,以上示例中的尾随正斜杠是必需的。在Windows下,同样需要反斜杠。

还请注意,工作目录(您从中调用NASM的目录)仍需要包含“主”源代码文件,即命令本身需要输入文件作为参数。例如,上述调用仍然需要工作目录中的“ sourcecode.asm”,而不管附加的-i选项参数如何。如果“ sourcecode.asm”位于可选目录“ procedure_library”中,则NASM将返回fatal: unable to open input filei选项可以被视为%include 文件搜索参数。

............................................... ................................................... ................................................... .........

硬编码文件路径:

作为给定方法的替代方法,您可以直接在源文件中直接对文件路径进行硬编码。只需将文件的相对或绝对路径传递到%include指令。例如:

%include “/home/user/asmwork/procedure_library/input.asm”

或者,假设您从中调用NASM的当前工作目录为/home/user/asmwork/

%include “/procedure_library/input.asm"

............................................... ................................................... ................................................... .........

外部库:

用于管理代码复杂性的另一种选择,也许是一个更好的选择,将是在外部将过程库组装为自己的目标文件,并在创建最终的可执行程序时链接这两个文件。后者可能还会使您的过程可在不同程序之间重用。

请记住,如果要链接的文件不在工作目录中,则需要在链接描述文件中提供相对/绝对路径。根据您使用的程序,在调用过程中可能需要也可能不需要传递其他参数。例如,GNU链接器不需要任何其他可选参数,它只是要求您传递一个可行的文件路径:

executable: sourcecode.o ld -o executable sourcecode.o /home/case/asmwork/procedure_library/input.o

............................................... ................................................... ................................................... .........

指令位置:

尽管在这种情况下,可以在源代码中的任何位置包含该指令都是绝对好的,但是通常最好在源代码顶部附近使用%include指令。例如,考虑是否要包含一个宏文件,在这种情况下,NASM会沿着error: parser: instruction expected的行向您发送错误,因为在调用它们之前必须完全定义所有宏。