我尝试使用包含一个文件到我的boot.asm文件中
%include "input.asm"
Run Code Online (Sandbox Code Playgroud)
但每次我尝试编译它时都会收到错误消息,说nasm无法打开包含文件.
input.incIS与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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
错误消息:
D:\ ASMT\boot.asm:14:致命:无法打开包含文件`input.asm'
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允许和路径名之间有空格,并且是可选的)。
这是维护项目的首选方式。然而,就击键而言,这是一个相当长的命令。虽然,使用 aMakefile可以解决这个问题。
nb 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,类似于 ,因为所有宏必须在调用之前完全定义。
似乎NASM包含当前目录中的文件:
在当前目录中搜索包含文件(运行NASM时所在的目录,而不是NASM可执行文件的位置或源文件的位置),以及使用NASM命令行上指定的任何目录. -i选项.
如果您正在NASM从D:\ASMT您的情况下的另一个目录执行,那么它是不正常的是正常的.
资料来源:http://www.nasm.us/doc/nasmdoc4.html#section-4.6.1