从终端输入缓冲区加载到参数堆栈 [英] Load from the terminal input buffer to parameter stack

查看:111
本文介绍了从终端输入缓冲区加载到参数堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么此代码不起作用?

Why does this code not work?

TIB 10 ACCEPT
TIB SP@ 1 cells - 10 cmove

在该代码中,我尝试输入一个字符串并将其存储在终端输入缓冲区中,然后将其存储在参数堆栈中.

In that code I tried to enter a string and store it in the terminal input buffer and later store it on the parameter stack.

但是使用.S,我认为那是行不通的.

But with .S I see that does not work.

推荐答案

参数堆栈朝着内存不足的方向增长

该示例代码的主要问题是参数堆栈朝着内存不足的方向增长.因此,复制目标的起点应位于较高的内存地址(在现有/定义的参数堆栈内).因此,而不是

The parameter stack grows towards low memory

The main problem with the sample code is that the parameter stack grows towards low memory. So the starting point for the destination of the copy should be at a higher memory address (inside the existing/defined parameter stack). So instead of

TIB SP@ 1 cells - 10 cmove

应为:

TIB SP@ 1 cells + 10 cmove

字符串的内存分配

下一个问题是参数堆栈上没有足够的存储空间来存储字符串. ACCEPT剩下一个单元(在32位系统上为四个字节),即实际的字符数.使用示例输入"user10181"(9个字符),

Memory allocation for the string

The next problem is that there is not enough storage for the string on the parameter stack. ACCEPT has left over one cell (four bytes on a 32-bit system), the actual number of characters. With sample input "user10181" (9 characters),

TIB 10 ACCEPT

导致:

.S <1> 9  ok

暂时忘记了这个额外的元素, 1 ,出于详细说明的目的,我们在参数堆栈上分配了四个单元格(实际值,例如235,无关紧要),在32位系统上为16个字节:

Forgetting about that extra element for the moment1, for the purpose of this elaboration, we allocate four cells on the parameter stack (the actual value, for example, 235, does not matter), 16 bytes on a 32-bit system:

235 DUP DUP DUP

然后TIB SP@ 1 cells + 10 cmove的结果是:

.S <5> 9 235 8241 541085779 541215060  ok

我们看到四个单元中的三个(每个单元有四个字节)已被cmove覆盖(如预期).

We see that three of the four cells (each with four bytes) have been overwritten by cmove (as expected).

不幸的是,我们复制的字节不符合预期.首先从

Unfortunately, our copied bytes are not as expected. Decoding the output for the three changed cells (that are in decimal), first from

8241 541085779 541215060

到十六进制:

2031 20405053 20424954

然后解码为 ASCII :

20 31 20 40 50 53 20 42 49 54
   1      @  P  S     B  I  T

然后反转(我们首先拥有高存储容量,而测试平台是小尾数):

And reversing (we had the high memory first and the test platform is little endian):

 "TIB SP@ 1 "

这是第二行TIB SP@ 1 cells + 10 cmove的前十个字符.因此很明显,终端输入缓冲区(TIB)太临时了,无法在这种情况下使用.

That is the first ten characters of our second line, TIB SP@ 1 cells + 10 cmove. Thus it is clear that the terminal input buffer (TIB) is too temporary to be used in this case.

第三个问题的解决方案是在要求用户输入之前编译所有代码.例如,将其写为inputOnStack:

The solution to the third problem is to have all the code compiled before we ask for user input. For instance, put it into a word, inputOnStack:

: inputOnStack TIB 10 ACCEPT 235 DUP DUP DUP TIB SP@ 1 cells + 10 cmove ;

结果是:

inputOnStack user10181  ok
.S <5> 9 235 24881 942747697 1919251317  ok

对应于"user10181",第十个字符为"a"(很可能来自inputOnStack中的"a").

That corresponds to "user10181" and the tenth character is "a" (most likely from the "a" in inputOnStack).

测试平台:

  • Raspberry Pi, model B.
  • Operating system: Raspbian, as installed by NOOBS 1.3.10, released 2014-09-09.
  • Gforth: version 0.7.0 (installed with sudo apt-get update; sudo apt-get install gforth)

1.该代码的更高级版本可以使用实际的字符数.无论如何,如果将此代码集成到其他代码中,则应该采用一种或另一种方法来保持堆栈平衡.

这篇关于从终端输入缓冲区加载到参数堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆