我正在尝试使用Mac工具使jonesforth在最新的MacBook上开箱即用。
我开始将所有内容转换为64位并使用mac汇编程序语法。
我可以组装东西,但立即遇到了奇怪的段错误。
/* NEXT macro. */
.macro NEXT
lodsq
jmpq *(%rax)
.endm
...
/* Assembler entry point. */
.text
.globl start
.balign 16
start:
cld
mov %rsp,var_SZ(%rip) // Save the initial data stack pointer in FORTH variable S0.
mov return_stack_top(%rip),%rbp // Initialise the return stack.
//call set_up_data_segment
mov cold_start(%rip),%rsi // Initialise interpreter.
NEXT // Run interpreter!
.const
cold_start: // High-level code without a codeword.
.quad QUIT
QUIT是通过宏defword这样定义的:
.macro defword
.const_data
.balign 8
.globl name_$3
name_$3 :
.quad $4 // link
.byte $2+$1 // flags + length byte
.ascii $0 // the name
.balign 8 // padding to next 4 byte boundary
.globl $3
$3 :
.quad DOCOL // codeword - the interpreter
// list of word pointers follow
.endm
// QUIT must not return (ie. must not call EXIT).
defword "QUIT",4,,QUIT,name_TELL
.quad RZ,RSPSTORE // R0 RSP!, clear the return stack
.quad INTERPRET // interpret the next word
.quad BRANCH,-16 // and loop (indefinitely)
...more code
运行此命令时,我第一次在NEXT宏中遇到段错误:
(lldb) run
There is a running process, kill it and restart?: [Y/n] y
Process 83000 exited with status = 9 (0x00000009)
Process 83042 launched: '/Users/klapauciusisgreat/jonesforth64/jonesforth' (x86_64)
Process 83042 stopped
* thread #1, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x0000000100000698 jonesforth`start + 24
jonesforth`start:
-> 0x100000698 <+24>: jmpq *(%rax)
0x10000069a <+26>: nopw (%rax,%rax)
jonesforth`code_DROP:
0x1000006a0 <+0>: popq %rax
0x1000006a1 <+1>: lodsq (%rsi), %rax
Target 0: (jonesforth) stopped.
rax确实指向了我认为是取消引用的地址,DOCOL:
(lldb) register read
General Purpose Registers:
rax = 0x0000000100000660 jonesforth`DOCOL
所以一个谜是:
1)为什么RAX指向DOCOL而不是QUIT?我的猜测是该指令已执行一半,而间接结果存储在rax中。好的文档说明?2)为什么出现段错误?
我在原始文件中注释掉了原始文件段设置代码brk来建立数据段。另一个[implementation]也根本没有调用它,因此我认为我也可以忽略它。在Catalina上的64位二进制文件中,如何通过syscall设置段权限有什么魔术? make命令几乎是标准的jonesforth之一:
jonesforth: jonesforth.S
gcc -nostdlib -g -static $(BUILD_ID_NONE) -o $@ $<
对于可以散发出的光感到非常高兴。我知道我没有提供很多细节,很高兴在这里或离线提供它。
P.S。是的,我可以让jonesforth在docker映像中完美工作,但这并不重要。我真的希望它能在Catalina上以64位格式开箱即用。
好的,如果我感到羞耻,我会脸红。
原始代码有类似内容
mov $cold_start,%rsi
并且苹果汇编程序抱怨无法在64位二进制文件中使用32个立即寻址。
已尝试
mov $cold_start(%rip),%rsi
但是那也不起作用。所以我尝试过
mov cold_start(%rip),%rsi
它组装了,但是当然取消了对cold start
的引用,这不是我所需要的。
显然,正确的方法是
lea cold_start(%rip),%rsi
这似乎按预期工作。