【发布时间】:2020-09-29 17:35:19
【问题描述】:
我试图在我的应用程序中包含我的操作系统的引用而不包含代码,因为代码已经在内存中。有没有办法只在 nasm 中包含引用(如 os_syscall_reboot ias at 0xda0e)?
【问题讨论】:
-
您可以为此使用动态链接,但为系统调用定义一个入口点可能更容易,该系统调用基于某个寄存器中的函数代码进行调度。或者多个入口点的跳转表。
我试图在我的应用程序中包含我的操作系统的引用而不包含代码,因为代码已经在内存中。有没有办法只在 nasm 中包含引用(如 os_syscall_reboot ias at 0xda0e)?
【问题讨论】:
os_syscall_reboot equ 0xda0e 定义一个汇编时常量将适用于某些使用它的方式,包括 call os_syscall_reboot 在某些情况下。
使用nasm -felf32,使用ld链接到静态ELF可执行文件:
os_syscall_reboot equ 0xda0e
call os_syscall_reboot
+ nasm -felf32 -Worphan-labels foo.asm
+ ld -melf_i386 -o foo foo.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
foo: file format elf32-i386
Disassembly of section .text:
08049000 <__bss_start-0x1000>:
8049000: e8 09 4a fc f7 call da0e <os_syscall_reboot>
(我很惊讶 os_syscall_reboot 将其作为符号名称 objdump -drwC -Mintel 可以看到。我只将它定义为带有 equ 的汇编时间常数,而不是 org + 标签或任何东西。)
但是使用nasm -felf64,它会使用 0xda0e-5 作为 rel32 偏移量,而不是绝对目标。(NASM 版本 2.14.02,在 x86-64 Arch GNU/Linux 上)。即它跳转到$ + 0xda0e,这非常奇怪。
...
401000: e8 0a da 00 00 call 40ea0f <__bss_start+0xca0f>
YASM -felf64 按预期组装。
401000: e8 09 ca c0 ff call da0e <__bss_start-0x3f45f2>
【讨论】:
global foo 和使用它的文件中的extern foo 是使符号跨文件可见的正常方法。您仍然可以使用链接器;组装成一些目标文件格式(例如-felf32),并且只在末尾制作一个带有ld的平面二进制文件,以将这些.o文件与符号结合起来。或者 %include 你所有的 .asm 文件到一个版本中,以便直接使用 -fbin。