|
|
2008/3/26(Wed) 14:48:27|NO.14597
はじめまして。
マシン語を初めて使おうと思ったのですが、エラーが起きてしまって・・・。
callfuncの時にエラーが起きているみたいなんですが、どこが間違っているか教えてください><
;テスト用プログラム
#uselib "kernel32.dll"
#func global VirtualProtect "VirtualProtect" var,int,int,var
#define global exedim(%1,%2)dim %1,%2:VirtualProtect %1, %2*4,$40,AZSD
#module "MachineCode"
#deffunc hikaku var p1,var p2,int p3
if phika=0{exedim hika,8 : phika=varptr.hika
hika.0=$53EC8B55,$085D8B52,$8A0C558B,$3A101D44,$74101544
hika.5=$0001B807,$02EB0000,$5B5AC033 }
prm=varptr.p1,varptr.p2,p3
return callfunc(prm,phika,3)
#global
a="a book"
b="a bank"
repeat 6
hikaku a,b,cnt
if stat=1:o++:else:n++
mes "一致:"+o+",不一致:"+n
loop
;マシン語ソース
.386
.MODEL TINY,STDCALL
OPTION SEGMENT:USE32
.CODE
hikaku PROC , p1:ptr DWORD, p2:ptr DWORD, p3
push ebx
push edx
mov ebx, p1
mov edx, p2
mov al, byte ptr[ebx+p3]
cmp al, byte ptr[edx+p3]
je lp1
mov eax, 1
jmp lp2
lp1: xor eax, eax
lp2: pop edx
pop ebx
ret
hikaku ENDP
END hikaku
|
|
2008/3/26(Wed) 17:38:32|NO.14601
procディレクティブ内部のpopに惑わされているのでは?
とりあえず
hika.0 = $8BEC8B55, $558B1045, $0CBE0F08, $0C558B02
hika.5 = $0204BE0F, $940FC82B, $01E183C1, $C35DC18B
に置き換えてみてください。
C言語コードは
/* 私の使っているコンパイラでは
p1[offset] == p2[offset]とすると
最適化がかかってだめでした。
*/
int hikaku(char *p1, char *p2, int offset)
{
return (p1[offset] - p2[offset]) == 0;
}
|
|
2008/3/26(Wed) 19:05:17|NO.14602
同様のエラーが発生し、終了してしまうようです…。
私の環境が影響しているのでしょうか?
(WinXP sp2)
|
|
2008/3/26(Wed) 20:25:34|NO.14603
まず、varptrの使い方が間違ってます。
varptr.p1 ではなくて varptr(p1)
逆汗してみましたが
byte ptr[ebx+p3]
の書き方では、別の意味に取られてるようですね。
p3をレジスタに代入してから使えばいいと思います。
以下は、いでじまさんのコードを逆汗したものです
:00000000 55 push ebp
:00000001 8BEC mov ebp, esp
:00000003 53 push ebx
:00000004 52 push edx
:00000005 8B5D08 mov ebx, dword ptr [ebp+08]
:00000008 8B550C mov edx, dword ptr [ebp+0C]
:0000000B 8A441D10 mov al, byte ptr [ebp+ebx+10] ▲
:0000000F 3A441510 cmp al, byte ptr [ebp+edx+10] ▲
:00000013 7407 je 0000001C
:00000015 B801000000 mov eax, 00000001
:0000001A EB02 jmp 0000001E
:0000001C 33C0 xor eax, eax
:0000001E 5A pop edx
:0000001F 5B pop ebx
arctanさんのは、配列のインデックスが間違ってます。1要素飛び抜かしてしまってる。
hika.5 を hika.4 に変更すれば動きます。
#uselib "kernel32.dll"
#func global VirtualProtect "VirtualProtect" var,int,int,var
#define global exedim(%1,%2) dim %1,%2:VirtualProtect %1, %2*4,$40,AZSD
#module "MachineCode"
#deffunc hikaku var p1,var p2,int p3
if phika=0 {
exedim hika,8 : phika=varptr(hika)
hika.0 = $8BEC8B55, $558B1045, $0CBE0F08, $0C558B02
hika.4 = $0204BE0F, $940FC82B, $01E183C1, $C35DC18B
}
prm = varptr(p1), varptr(p2), p3
return callfunc(prm, phika, 3)
#global
a="a book"
b="a bank"
repeat 6
hikaku a, b, cnt
if stat=1:o++:else:n++
mes "一致:"+o+",不一致:"+n
loop

| |
|
2008/3/26(Wed) 20:48:30|NO.14604
あらっ、varptr.p1 の書き方でも問題なく動くねw
それと、いでじまさんのマシン語コードは ret が無いです;
|
|
2008/3/26(Wed) 21:36:41|NO.14606
aさん、ありがとうございます。
p3の意味の取り方が違うように解釈されていたようです。
(この辺りはHSPのシステムとかみ合ってないのでしょうか?)
;修正後コード
.386
.MODEL TINY,STDCALL
OPTION SEGMENT:USE32
.CODE
hikaku PROC , p1:ptr DWORD, p2:ptr DWORD, p3
push ebx
push edx
push ecx
mov ebx, p1
mov edx, p2
mov ecx, p3
mov al, byte ptr[ebx+ecx]
cmp al, byte ptr[edx+ecx]
je lp1
mov eax, 1
jmp lp2
lp1: xor eax, eax
lp2: pop ecx
pop edx
pop ebx
ret
hikaku ENDP
END hikaku
言葉を返すようで申し訳ないですが、retは最初からソースには入っています。
けれど逆汗したときに無かったということは、どこかの段階で削除されてしまったのでしょうか…。
*.binで出力されたデータを自作ツールで格納しているので、そのツールのバグかもしれません。
無事動作いたしましたので、解決にチェックを入れさせていただきます。
ご回答いただいたarctanさん、aさん、本当にありがとうございました。^^
|
|
2008/3/27(Thu) 17:03:51|NO.14621
|
|
2008/3/28(Fri) 15:17:01|NO.14659
>arctanさんのは、配列のインデックスが間違ってます。1要素飛び抜かしてしまってる。
いまさらこんなことをいうのもなんですが、
へんな回答をしてすみません。
以後気をつけます。
|
|