【问题标题】:Can't include a file in NASM不能在 NASM 中包含文件
【发布时间】:2013-08-07 06:44:43
【问题描述】:

我尝试使用

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

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

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

编辑:这是包含的代码:

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

输入.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'

【问题讨论】:

  • 刚刚尝试使用我的 NASM 版本(0.98),它可以正常工作,正如预期的那样......可能是您的版本中的错误。您是否尝试过在 .inc 文件中添加 .asm 扩展名?
  • 是的,不管我怎么试,还是说打不开。 Include.inc 是一个普通的 asm 文件,带有一些标签和代码。
  • %include "input.inc" 不会包含名为 Include.inc 的文件。
  • @CharlesBailey,我的错,应该在那里写 input.inc。另外,我刚刚更新到 NASM 2.10.09(使用的是 2.07 prev),我仍然得到同样的错误
  • @TheMorfeus 也许试试 YASM...

标签: assembly nasm


【解决方案1】:

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

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

如果您是从另一个目录执行NASM D:\ASMT 在您的情况下,它不起作用是正常的。

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

【讨论】:

  • 哦,谢谢,将 -I D:/ASMT 添加到 nasm 启动命令有效。
【解决方案2】:

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

%include "input.asm"

需要注意的是,NASM 假设所有文件都在当前工作目录中,例如运行 NASM 的目录。如果将文件传递给%include 指令,并且该文件不能位于当前工作目录中,则 NASM 将返回以下错误:

fatal: unable to open include file

如已在接受的答案中给出的那样,一种解决方案是使用 -i 选项在 NASM 命令行上指定任何额外引用的目录。例如,让我们假设一个名为“print_string”的“include”文件位于“procedure_library”目录中,并且该目录不是 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 file。 i 选项可以被认为是一个 %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 的行给您一个错误,因为所有宏在调用之前都必须完全定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    相关资源
    最近更新 更多