Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly Ti-89 68k组件中的函数指针_Assembly_Compiler Construction_68000_B - Fatal编程技术网

Assembly Ti-89 68k组件中的函数指针

Assembly Ti-89 68k组件中的函数指针,assembly,compiler-construction,68000,b,Assembly,Compiler Construction,68000,B,几个月来,我一直在尝试为我的Ti-89构建一个自制的brew B交叉编译器,现在终于到了我想要生成计算器执行的程序集的时候了。语言是“B”,因为只有一种类型是整数/指针。我不明白如何在这个平台上实现函数指针。我考虑通过以下方式实现函数指针: 使用立即数值存储第一条指令的地址 使用程序计数器和偏移量导出第一条指令的地址 仅存储偏移量并在跳转时计算第一条指令的地址 第一种方法肯定行不通,因为Ti-89上的汇编程序在执行之前会复制到RAM中。我无法在编译时知道函数将位于何处。此外,根据第24页的T

几个月来,我一直在尝试为我的Ti-89构建一个自制的brew B交叉编译器,现在终于到了我想要生成计算器执行的程序集的时候了。语言是“B”,因为只有一种类型是整数/指针。我不明白如何在这个平台上实现函数指针。我考虑通过以下方式实现函数指针:

  • 使用立即数值存储第一条指令的地址
  • 使用程序计数器和偏移量导出第一条指令的地址
  • 仅存储偏移量并在跳转时计算第一条指令的地址
第一种方法肯定行不通,因为Ti-89上的汇编程序在执行之前会复制到RAM中。我无法在编译时知道函数将位于何处。此外,根据第24页的Ti-89/Ti-92 Plus开发人员指南,“ASM程序可能在堆垃圾收集期间移动。指向重写系统代码的指针将变得无效。”这意味着第二种方法也不一定有效,因为堆垃圾回收可能在计算第一条指令的地址之后发生。假设它所说的程序移动是正确的,这可能会导致整个函数移动。第三种方法将在特定情况下工作,但问题是我不一定知道在汇编程序中调用函数的位置。因此,我需要为函数可以调用的每个位置使用不同的偏移量,而据我所知,我无法计算该偏移量

TIGCC允许函数指针,那么它们是如何实现的呢?有什么我遗漏的吗

链接:

  • Ti-89/Ti-92开发者指南:
  • TIGCC:
  • 我的项目:

我听从了@Lourger的建议。程序集似乎只是将地址推送到堆栈上,而没有更多信息。通过测试,如果我的函数名为
my_func
,则程序集看起来像是
move.l\my_func,-4(%fp)
,它只是在按函数指针。我猜汇编器会将其转换为PC机的直接相对地址,而不仅仅是二进制文件中的实际地址。这意味着我之前引用的文档读错了。我想它想说的是,你不能引用内存中二进制文件中的地址,但你可以引用内存中临时副本中的地址。这将更有意义,因为无论如何,当汇编程序运行时,操作系统不会真正在后台运行。我必须假设垃圾收集只能在程序执行后发生。

如果要获取同一编译单元中函数的地址,应该使用PC相对寻址。您可以使用
lea
(加载有效地址)将地址存储在任何地址寄存器中(
a0
-
a6
。从技术上讲,
a7
也可以工作,但不要这样做。
a6
通常也被保留为帧指针):

可以使用
jsr(a2)
(跳转到子例程),或者在某些情况下仅使用
jmp(a2)
(如果堆栈上的参数已经与
myfunc
所期望的函数参数匹配,则本质上是尾部跳转)来调用它

或者,您可以使用
pea
(推送有效地址)在堆栈上推送地址:

pea   myfunc(PC)
这可以是一个函数参数,或者如果它位于堆栈的顶部,您将使用下一个
rts
跳转到该地址。例如,如果您有一个函数的结尾是这样的:

    lea  myfunc(PC),a2
; some other code (not changing a2, not messing with the stack)
    bsr  foo   ; local subroutine
    jsr  (a2)
    rts
你也可以写:

    pea  myfunc(PC)
; some other code (not messing with the stack)
    bra  foo  ; tail call to local subroutine foo
              ; on return this will jump to myfunc
              ; when myfunc ends, it returns to the caller of this function

TIGCC是否支持gcc的-s选项来输出Ti-89组件?@Lowerer是的,它支持!酷。您可以编写使用函数指针的最简单的C程序,并查看
-S
选项为您提供了什么。是否希望函数指针指向系统函数,指向不同编译单元或相同编译单元中的函数?@chtz我需要一个指向相同编译单元的函数指针——可能是您在禁用优化的情况下编译的,否则它不需要将函数指针存储在堆栈上(取决于您对它所做的操作)。无论如何,不,它可能正在使用带有绝对地址的
mov
-立即数(由链接器填写和/或修复运行时)。TIGCC如何访问静态数据,例如将
static int foo
的地址传递给
extern void bar(int*)
函数?@Peter Cordes Yes,编译优化级别
-O0
。当我进行测试时,编译器在可执行文件的末尾为变量保留空间,并用
pea foo
加载指针,这对于将foo的地址推送到堆栈上来说只有68k。我将反汇编二进制文件,以确保它没有使用PC间接寻址。如果你可以使用即时地址,你要么有一个重新定位的加载程序,要么你的汇编程序将所有内容转换为PC相对地址。两者都是可能的。如果可执行文件在执行过程中像文档中所说的那样移动,这会中断,不是吗?我将其重新解释为,存储的可执行文件可以移动,但不能移动正在运行的RAM中的副本。如果可执行文件在“执行期间”移动,则会出现更大的问题。我为TI-92+编程已经有一段时间了,但这永远不会发生。PC相对寻址的最大优点是,内核在启动之前不需要计算任何绝对地址。这对于跳转到不超过+-32767字节的子例程非常有效,甚至可以用于“移动代码”(我认为TI上不会发生这种情况)如果您可以确保它不会在寄存器负载和实际跳转之间移动。
    pea  myfunc(PC)
; some other code (not messing with the stack)
    bra  foo  ; tail call to local subroutine foo
              ; on return this will jump to myfunc
              ; when myfunc ends, it returns to the caller of this function