More ... | Note:HSP用語辞典
オフセット(Offset)
実引数と、仮引数というのがある。
メモリの確保
例: ;HSP2.61ver de run
#include "llmod.as"
print "変数の場合"
print "------------------------------------------------------------------"
a = 0 :getptr pa,a :hpa = pa
str hpa,23 ;paの数値を8桁の16進数文字列に変換
print "a の内容: "+a+" | 番地[10進数]: "+pa+" | 番地[16進数]: 0x"+hpa
b = 0 :getptr pb,b :hpb = pb
str hpb,23 ;pbの数値を8桁の16進数文字列に変換
print "b の内容: "+b+" | 番地[10進数]: "+pb+" | 番地[16進数]: 0x"+hpb
print "------------------------------------------------------------------"
print "配列変数の場合"
print "------------------------------------------------------------------"
repeat 4
ary.cnt = cnt : getptr pary.cnt,ary.cnt :hpary = pary.cnt :str hpary,23
print "ary."+cnt+" の内容: "+ary.cnt+" | 番地[10進数]: "+pary.cnt+" | 番地[16進数]: 0x"+hpary
loop
stop
バッファオーバーフロー
宣言 i=1 ; 変数iは宣言(数値型)、確保(64byte)、代入(数値)されている。
s="1" ; 変数sは宣言(文字列型)、確保(64byte)、代入(文字列)されている。
; 変数の型は代入時に更新される。
poke sary1,0,'H' ; 変数sary1は宣言(数値型)、確保(64byte)されている。
poke sary1,1,'S' ; 変数sary1は代入されていないので数値型変数。
poke sary1,2,'P'
mes "sary1 = "+sary1
if sary1!"HSP"{ ; 数値と文字列の比較は(基本的)にできない
mes "sary1 isn't \"HSP\"."
}else{
mes "sary1 is \"HSP\"."
}
// だが・・・
str sary2 ; 変数sary2は宣言(文字列型)、確保(64byte)されている。
poke sary2,0,'H'
poke sary2,1,'S'
poke sary2,2,'P'
mes "sary2 = "+sary2
if sary2!"HSP"{ ; 文字列と文字列の比較
mes "sary2 isn't \"HSP\"."
}else{
mes "sary2 is \"HSP\"."
}
// ちなみに・・・リトルエンディアン環境で、
// sary1のメモリイメージ
// H S P \0
// 48 53 50 00
//--------------
// 00 50 53 48 = 5264200(リトルエンディアンではLSBがアドレスの若い位置に来る)
if sary1!"5264200"{ ; 数値と数値文字列との比較はできる。
mes "sary1 isn't number\"5264200\"."
}else{
mes "sary1 is number\"5264200\"."
}
stop
/*
*** メモリへの格納順序方式 ***
一般的にメモリの一つのアドレスに格納できるバイト幅は``1byte''である。
なので、2byte以上のバイト幅を持つデータは分割してメモリに格納しなければならない。
プロセッサ毎に以下のような方式がある。
[Little endian]
主にIntel系CPUで採用されている方式。
この方式は最下位byte(Least Significant Byte/Bit - LSB)からメモリに割り当てていく方式である。
[Big endian]
主にMotorola系CPUで採用されている方式。
この方式はリトルエンディアン方式とは逆に、最上位byte(Most Significant Byte/Bit - MSB)から割り当てていく方式である
[``hello,world''のメモリイメージ]
+---+--+--+--+--+--+--+--+--+--+--+--+--+
|AZS| h| e| l| l| o| ,| w| o| r| l| d|\0|
+---+--+--+--+--+--+--+--+--+--+--+--+--+
|BiE|68|65|6c|6c|6f|2c|77|6f|72|6c|64|00|
+---+--+--+--+--+--+--+--+--+--+--+--+--+
|LiE|00|64|6c|72|6f|77|2c|6f|6c|6c|65|68|
+---+--+--+--+--+--+--+--+--+--+--+--+--+
[``HSP''のメモリイメージ]
+---+-----+-----+-----+--+
|AZS| H | S | P |\0|
+---+-----+-----+-----+--+
|BiE|67|82|72|82|6f|82|00|
+---+-----+-----+-----+--+
|LiE|00|82|6f|82|72|82|67|
+---+--+-----+-----+-----+
*/
アドバイス
予約語例えばllmod.asにはgetptrという変数のアドレスを取得する命令がある。 ; getptr命令の正しい使い方
#include "llmod.as"
n=5 : m=0
mes "n="+n
mes "m="+m
getptr pn,n ; nのアドレスを取得
ll_peek4 m,pn ; nのアドレスから4バイトをmに読み込む
mes "n="+n
mes "m="+m
stop
; getptrは命令じゃない
n=5 : m=0
mes "n="+n
mes "m="+m
getptr=pn,n ; nのアドレスを取得・・・じゃないよ
; ll_peek4は使っちゃダメです。
mes "n="+n
mes "m="+m
mes "getptr.0="+getptr.0
mes "getptr.1="+getptr.1
stop
この通りgetptr命令を定義しているllmod.asがインクルードされていない場合、 予約語にない単語は変数として扱われます。広く考えれば変数として使えない名前≒予約語(命令語・システム変数・プリプロセッサ定数など) 用語区分HSP3になってからAPI呼び出しが簡単に、あるいはHSPの機能かのように呼び出せるようになったので、初心者も手を出しやすくなったと思います。(初心者も簡単に扱える、という意味ではなく。)そうなってくるとHSP用語だけではなく、API用語、またCOMも扱えるようになった->COM関連の用語も「HSP用語」に入ってくるのかな、と思います。そういったものが五十音順で入り混じってくると調べにくい(読みにくい)一面もあると思います。というわけでHSP用語辞典とは別でAPI用語、COM用語と分ける必要はあるかどうか、という意見をお聞かせください。
モジュール変数について「モジュール変数」を追加しました。しかしまだ満足いきません。以下のような場合、全てを「モジュール変数」と括ってしまうのは語弊があるように思います。 #module "MModuleStructure" m_x, m_y, m_z ; ここでのモジュール名の""の有無は問題ないけど...
#modinit
modname = "MModuleStructure"
modarg = 3
return
#global
newmod m_exp, MModuleStructure ; ここでのモジュール名の""の有無はコンパイルに影響を与える。
; どっちかというと""で囲みたいです。
区別するべき変数は「m_x , m_y , m_z ( 仮:モジュールメンバ変数? )」「modname , modarg ( 仮:モジュール(内)変数? )」「m_exp ( 仮:モジュール型変数? )」の3種類だと思いますが、これ以外にいい名称はないでしょうか...? < kz3
|