x86 32位程序集中的BrainF*ck解释器



我开始在32位x86程序集中为我的操作系统编写BrainF*ck解释器。我已经用C编写了一个可以工作的程序,并试图在汇编中实现它,但用汇编编写的程序不打印任何输出。

我还是组装新手,所以我想我只是犯了一些初学者的错误。我唯一能想到的就是我把地址搞砸了。如果有人能指出我做错了什么,我会非常高兴。

我用相同的输入测试了C和汇编程序:

-[--->+<]>---.+[----->+++<]>.[--->+<]>+.[--->++<]>-.++++.

应打印RexOS

我创建了一个C代码的pastebin,如果这有助于理解我试图实现的目标:粘贴式

我的汇编代码如下:

.intel_syntax noprefix
.section .data
TAPE:
.zero 30000
.section .text
.global interpret
interpret:
push ebp                // prologue
mov ebp, esp
mov edx, [ebp+8]        // getting the input string
mov edi, offset TAPE    // a pointer to the tape
xor ecx, ecx            // stores current char
// inner loop counter
loop:
mov cl, byte ptr [edx]  // getting the current char
inc edx                 // increase the index to the next char
cmp cl, 0               // if we reached the end of the string
je exit                 // return the length
cmp cl, '>'
je pinc                 // increment the pointer
cmp cl, '<'
je pdec                 // decrement the pointer
cmp cl, '+'
je vinc                 // increment value at index
cmp cl, '-'
je vdec                 // decrement value at index
cmp cl, '.'
je prnt                 // print the value at index
cmp cl, ','
je read                 // read character from stdin
cmp cl, ']'
je bend                 // end of bracket
jmp loop
pinc:
inc edi
jmp loop
pdec:
dec edi
jmp loop
vinc:
inc byte ptr [edi]
jmp loop
vdec:
dec byte ptr [edi]
jmp loop
prnt:
push edx
push dword ptr [edi]
call putchar
add esp, 4
pop edx
jmp loop
read:
call getchar
mov byte ptr [edi], al
jmp loop
bend:
cmp byte ptr [edi], 0
je loop
mov ch, 1
ilst:
cmp ch, 0
jle loop
dec edx                 // jump to the previous index
mov cl, byte ptr [edx]  // getting the current char
cmp cl, '['
je dclp                 // decrease internal loop counter
cmp cl, ']'
je inlp                 // increase internal loop counter
jmp ilst
inlp:
inc ch
jmp ilst
dclp:
dec ch
jmp ilst
exit:
mov esp, ebp            // epilogue
pop ebp
ret

我终于解决了这个问题。我所需要做的就是将指针增量移动到循环的末尾,并在序言(ebx(中保存额外的寄存器,然后在后记中恢复寄存器。还需要保存和恢复prnt和扫描部分中的寄存器。

我的最终工作代码如下:

.intel_syntax noprefix
.section .data
TAPE:
.zero 30000
.section .text
.global interpret
interpret:
push ebp                // prologue
mov ebp, esp
push ebx
xor eax, eax            // loop counter
mov ebx, offset TAPE    // a pointer to the tape
mov edx, [ebp+8]        // getting the input string

clrt:                       // clear TAPE
cmp eax, 30000
je loop
mov byte ptr [ebx+eax], 0
inc eax
jmp clrt
loop:
mov cl, byte ptr [edx]  // getting the current char
cmp cl, 0               // if we reached the end of the string
je exit                 // return the length
cmp cl, '>'
je pinc                 // increment the pointer
cmp cl, '<'
je pdec                 // decrement the pointer
cmp cl, '+'
je vinc                 // increment value at index
cmp cl, '-'
je vdec                 // decrement value at index
cmp cl, '.'
je prnt                 // print the value at index
cmp cl, ','
je read                 // read character from stdin
cmp cl, ']'
je bend                 // end of bracket
ptlp:                       // postloop
inc edx                 // increment the input pointer
jmp loop                // continue the loop
pinc:
inc ebx
jmp ptlp
pdec:
dec ebx
jmp ptlp
vinc:
inc byte ptr [ebx]
jmp ptlp
vdec:
dec byte ptr [ebx]
jmp ptlp
prnt:
push edx
push dword ptr [ebx]
call putchar
add esp, 4
pop edx
jmp ptlp
read:
push edx
call getchar
mov byte ptr [ebx], al
pop edx
jmp ptlp
bend:
cmp byte ptr [ebx], 0
je ptlp
mov ch, 1
ilst:
cmp ch, 0
jle ptlp
dec edx                 // jump to the previous index
mov cl, byte ptr [edx]  // getting the current char
cmp cl, '['
je dclp                 // decrease internal loop counter
cmp cl, ']'
je inlp                 // increase internal loop counter
jmp ilst
inlp:
inc ch
jmp ilst
dclp:
dec ch
jmp ilst
exit:
pop ebx                 // epilogue
mov esp, ebp
pop ebp
ret

最新更新