我的 BF 到 NASM 编译器使 asm 对于一个已知的工作 BF 程序不起作用
My BF to NASM compiler makes asm that doesn't work, for a known working BF program
Meta:总的来说,我是汇编语言的新手,尤其是 NASM。在玩了几个晚上 NASM 之后,我有足够的信心编写一个简单的 Brainf*uck 编译器:它将 bf 代码作为输入并吐出一些 NASM 代码。编译器写在Python.
问题:编译器似乎适用于简单的情况——例如,“Helloworld”程序(在下面列出)。在其他情况下,例如著名的 Mandelbrot 程序在调用后很快就会出现严重的段错误。
我使用的是一种非常直接的方法:
- 作为当前内存指针,我正在使用
r10
寄存器
- bf 磁带本身对应
memory
标签。
- 要滑过磁带(
<
和 >
操作)我会 add/sub r10, value
,例如add r10, 10
- 修改磁带内容我做
add/sub byte [memory+r10], byte value
问题:你能马上发现任何完全错误的地方吗?我没有为 Mandelbrot(其中的段错误)提供 NASM 输出,因为它相当冗长。
global _start
section .data
memory: times 32768 db 0
section .text
_start:
xor r10, r10
call l0
mov rax, 60
mov rdi, 0
syscall
l1: ; [>+++++++>++++++++++>+++>+<<<<-]
add r10, 1
add byte [memory+r10], byte 7
add r10, 1
add byte [memory+r10], byte 10
add r10, 1
add byte [memory+r10], byte 3
add r10, 1
add byte [memory+r10], byte 1
sub r10, 4
sub byte [memory+r10], byte 1
cmp byte [r10+memory], byte 0
jne l1
ret
l0: ; ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.
add byte [memory+r10], byte 10
call l1
add r10, 1
add byte [memory+r10], byte 2
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
add byte [memory+r10], byte 1
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add byte [memory+r10], byte 7
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add byte [memory+r10], byte 3
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
add byte [memory+r10], byte 2
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
sub r10, 2
add byte [memory+r10], byte 15
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add byte [memory+r10], byte 3
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
sub byte [memory+r10], byte 6
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
sub byte [memory+r10], byte 8
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
add byte [memory+r10], byte 1
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
ret
更新:
最新版本的翻译器可以找到here。
我想通了 - 问题出在对 BF 逻辑本身的轻微误解。
在上面的示例中,l1
标签应如下所示:
l1: ; [>+++++++>++++++++++>+++>+<<<<-]
cmp byte [memory+r10], byte 0
jne .cont
ret
.cont:
add r10, 1
add byte [memory+r10], byte 7
add r10, 1
add byte [memory+r10], byte 10
add r10, 1
add byte [memory+r10], byte 3
add r10, 1
add byte [memory+r10], byte 1
sub r10, 4
sub byte [memory+r10], byte 1
cmp byte [memory+r10], byte 0
jne l1
ret
Meta:总的来说,我是汇编语言的新手,尤其是 NASM。在玩了几个晚上 NASM 之后,我有足够的信心编写一个简单的 Brainf*uck 编译器:它将 bf 代码作为输入并吐出一些 NASM 代码。编译器写在Python.
问题:编译器似乎适用于简单的情况——例如,“Helloworld”程序(在下面列出)。在其他情况下,例如著名的 Mandelbrot 程序在调用后很快就会出现严重的段错误。
我使用的是一种非常直接的方法:
- 作为当前内存指针,我正在使用
r10
寄存器 - bf 磁带本身对应
memory
标签。 - 要滑过磁带(
<
和>
操作)我会add/sub r10, value
,例如add r10, 10
- 修改磁带内容我做
add/sub byte [memory+r10], byte value
问题:你能马上发现任何完全错误的地方吗?我没有为 Mandelbrot(其中的段错误)提供 NASM 输出,因为它相当冗长。
global _start
section .data
memory: times 32768 db 0
section .text
_start:
xor r10, r10
call l0
mov rax, 60
mov rdi, 0
syscall
l1: ; [>+++++++>++++++++++>+++>+<<<<-]
add r10, 1
add byte [memory+r10], byte 7
add r10, 1
add byte [memory+r10], byte 10
add r10, 1
add byte [memory+r10], byte 3
add r10, 1
add byte [memory+r10], byte 1
sub r10, 4
sub byte [memory+r10], byte 1
cmp byte [r10+memory], byte 0
jne l1
ret
l0: ; ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.
add byte [memory+r10], byte 10
call l1
add r10, 1
add byte [memory+r10], byte 2
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
add byte [memory+r10], byte 1
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add byte [memory+r10], byte 7
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add byte [memory+r10], byte 3
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
add byte [memory+r10], byte 2
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
sub r10, 2
add byte [memory+r10], byte 15
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add byte [memory+r10], byte 3
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
sub byte [memory+r10], byte 6
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
sub byte [memory+r10], byte 8
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
add r10, 1
add byte [memory+r10], byte 1
mov rax, 1
mov rdi, 1
lea rsi, [r10+memory]
mov rdx, 1
syscall
ret
更新:
最新版本的翻译器可以找到here。
我想通了 - 问题出在对 BF 逻辑本身的轻微误解。
在上面的示例中,l1
标签应如下所示:
l1: ; [>+++++++>++++++++++>+++>+<<<<-]
cmp byte [memory+r10], byte 0
jne .cont
ret
.cont:
add r10, 1
add byte [memory+r10], byte 7
add r10, 1
add byte [memory+r10], byte 10
add r10, 1
add byte [memory+r10], byte 3
add r10, 1
add byte [memory+r10], byte 1
sub r10, 4
sub byte [memory+r10], byte 1
cmp byte [memory+r10], byte 0
jne l1
ret