多字节存储和Forth中的提取 - 如何实现?

时间:2015-11-28 00:08:47

标签: arrays forth gforth

使用大型数组时,最好能够将数组调整为每个数字的特定字节数。大多数情况下,我希望快速例程将这样调整的多字节数读取到堆栈上的单个字节,相反地将单个字节存储在调整为一定数量字节的数组中。在64位系统中,需要其他单个数字数组,而不是一个字节(c @ c!)和八个字节(@!)。

那么如何实施

var jsonString = '{"result":[{"lot_no":"MT6261"},{"lot_no":"MT6262"},{"lot_no":"MT6263"}]}';

// create the data store
var store = Ext.create('Ext.data.Store', {
    pageSize: itemsPerPage,
    model: 'Assemble'
});
store.loadData(Ext.decode(jsonString).result); 

其中b是字节数。 cs这个词!似乎是作为

cs@ ( ad b -- n )
cs! ( n ad b -- )

但是cs @怎么样以及如何在没有sp @或类似词的纯ANS Forth中做到这一点?

3 个答案:

答案 0 :(得分:2)

Forth200 * x *委员会已花了相当多的时间来开发一个Memory Access单词集。由于它的大小,我们目前尚未将其纳入标准。

答案 1 :(得分:1)

兼容的方法是使用C@和按位操作。要在内存中使用与Forth系统相同的字节顺序,需要检测字节顺序并编译某些定义的合适版本。

\ These definitions use little-endian format in memory.
\ Assumption: char size and address unit size equal to 1 octet.

: MB! ( x addr u -- )
  ROT >R  OVER +  SWAP
  BEGIN  2DUP U>  WHILE  R> DUP 8 RSHIFT >R OVER C! 1+ REPEAT
  2DROP RDROP
;
: MB@ ( addr u -- x )
  0 >R  OVER +
  BEGIN  2DUP U<  WHILE  1- DUP C@ R> 8 LSHIFT OR >R  REPEAT
  2DROP R>
;

为了获得更高的性能,最好使用特定于实现的功能(包括W@T@Q@SP@等)甚至内联Forth-assembler。

请注意,通过DO循环的直接定义通常具有更差的性能(取决于优化器; SP-Forth / 4.21中为10%)。参考代码:

: MB! ( x addr u -- )
  OVER + SWAP ?DO DUP I C! 8 RSHIFT LOOP DROP
;
: MB@ ( addr u -- x )
  DUP 0= IF NIP EXIT THEN
  0 -ROT
  1- OVER + DO 8 LSHIFT I C@ OR -1 +LOOP
;

我们不能在第二种情况下使用?DO,因为减少了循环索引和+LOOP semantics:当索引越过“循环限制减去1 <之间的边界时,它会离开圆圈/ strong>和循环限制“。

答案 2 :(得分:1)

\ little-endian (eg. pc, android)
: mb! ( n ad i -- )  2>r here ! here 2r> cmove ;
: mb@ ( ad i -- n )  here 0 over ! swap cmove here @ ;

\ big-endian (eg. mac)
: mb! ( n ad i -- )  2>r here ! here cell + r@ - 2r> cmove ;
: mb@ ( ad i -- n )  here 0 over ! cell + over - swap cmove here @ ;

\ little-endian test
1 here ! here c@ negate .

当然HERE可以是任何一个细胞缓冲液。

感谢ruvim向前解析进程!