将Jonesforth移植到Macos Catalina

问题描述 投票:1回答:1

我正在尝试使用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位格式开箱即用。

macos assembly x86-64 att forth
1个回答
2
投票

好的,如果我感到羞耻,我会脸红。

原始代码有类似内容

mov $cold_start,%rsi

并且苹果汇编程序抱怨无法在64位二进制文​​件中使用32个立即寻址。

已尝试

mov $cold_start(%rip),%rsi

但是那也不起作用。所以我尝试过

mov cold_start(%rip),%rsi

它组装了,但是当然取消了对cold start的引用,这不是我所需要的。

显然,正确的方法是

lea cold_start(%rip),%rsi

这似乎按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.