関数 peek(D) を用いると,
アドレス D に格納された 1 バイト
(16 進 2 桁, 2 進 8 桁) のデータを覗く(peek)ことができる.
関数 poke(D,N) を用いると, アドレス D に
データ N を直接書き込む事が可能である.
ここで, N は から
の範囲のデータ
である.
通常のプログラムでこのような関数を利用する必要はないが, 計算機プログラミングの達人になるには これらの関数を援用して, メモリの様子が手にとるように理解できるようになるまで 頑張る必要があろう.
なお, poke であやまった場所にデータを書き込んでしまうと, システム全体が異常な動作におちいるので注意. どうしてそのような事態になるか説明できるだろうか?
[469] X="abc"; abc [470] D=get_addr(X); 139968704 [471] hex_dump(D,10); 0857c0c0: 07000000 98aa5308 0000 0 [472] type(X); 7 [473] hex_dump(0x0853aa98,10); 0853aa98: 61626300 00000000 656e 0 |
|
上の例では, hex_dump の出力 98 aa 53 08 より アドレス 08 53 aa 98 (後ろから読む) を読みとり, 手動でアドレスを入力する必要があった. 次の関数 get_body_addr はこのアドレスを一気に求める.
def get_body_addr(X) { A = get_addr(X); A3=peek(A+7); A2=peek(A+6); A1=peek(A+5); A0=peek(A+4); return(ishift(A3,-24)+ishift(A2,-16)+ishift(A1,-8)+A0); }
最後の ishift(A3,-24)+ishift(A2,-16)+ishift(A1,-8)+A0
は
A3*0x1000000+A2*0x10000+A1*0x100+A0
としてもよい.
これはたとえば 2進数を bit 左にシフトすることと,
その数を
倍 (
) するのは同じことなので
明らかであろう.
[469] X="abc"; abc [470] D=get_addr(X); 139968704 [471] hex_dump(D,10); 0857c0c0: 07000000 98aa5308 0000 0 [473] get_body_addr(X); 139700888 [474] poke(get_body_addr(X),0x41); 0 [475] X; Abc |
|
アドレス get_addr(X) より 始まるメモリ領域の最初のバイトは X に格納されているデータの 型番号である. この数は, 関数 type(X) の戻す値と一致している. たとえば次の例をみてみよう.
[496] X=10; 10 [497] type(X); 1 [498] hex_dump(get_addr(X),4)$ 085843b0: 01000001 [499] X=x^2-1; x^2-1 [500] type(X); 2 [501] hex_dump(get_addr(X),4)$ 085840c0: 02000000
C 等の一般的な言語での整数は, ``32 bit 整数'' とよばれ,
サイズが 32 bit である.
一番上位の bit を符号としてもちいるので,
扱うことのできる最大の正の整数は
となる.
C でこの数に
を加えると負の数となる.
Asir が標準的に用いている整数は , ``32 bit 整数'' でない. いわゆる bignum である. 数が大きくなっていったら動的に数のデータを格納するメモリの領域を広げて 計算をおこなう. したがって, 数の大きさの上限は, 計算機のメモリのサイズに依存するのみである. この様子を, 次のプログラムで眺めてみよう.
def naibu() { X = 2^16; for (I=0; I<4; I++) { print("X=",0); print(X); A = get_body_addr(X); print("address=",0); print(A); hex_dump(A,32); X = X*X; } }
|
|
[532] naibu()$ X=65536 address=140075328 08596140: 01000000 00000100 00000000 00000000 08596150: 01000000 00010000 00000000 00000000 X=4294967296 address=140075040 08596020: 02000000 00000000 01000000 00000000 08596030: 02000000 40806302 01000000 00000000 |
|
X=18446744073709551616 address=139038512 08498f30: 03000000 00000000 00000000 01000000 08498f40: 00000000 00000000 03000000 00bf9100 X=340282366920938463463374607431768211456 address=140029728 0858af20: 05000000 00000000 00000000 00000000 0858af30: 00000000 01000000 00000000 00000000 [533] |