HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2008
0806
arctan機械語でマンデルブロー集合6解決


arctan

リンク

2008/8/6(Wed) 16:24:25|NO.17931

マンデルブロー集合を探索するプログラムを作成するに当たって、
HSPでは速さに問題があったので機械語で作成しようと思ったのですが、
経験不足からか、エラーが出ます。
できれば、以下のコードの問題点を教えていただきたいです。

#uselib "kernel32.dll" #func VirtualProtect "VirtualProtect" var,int,int,var #define xdim(%1,%2) dim %1,%2: VirtualProtect %1,%2*4,$40,AZSD dim ColorTable, 191 repeat 191 hsvcolor cnt, 255, 255 ColorTable(cnt) = ginfo_r + (ginfo_g << 8) + (ginfo_b << 16) loop RealMin = -2.0 ImagMax = 1.25 step = 0.0052083333333333333333333333333333 prm.0 = hdc prm.1 = varptr(RealMin) prm.2 = varptr(ImagMax) prm.3 = varptr(step) prm.4 = 128 prm.5 = 480 prm.6 = 480 prm.7 = varptr(ColorTable) prm.8 = length(ColorTable) xdim fncode,67 fncode(0) = $83ec8b55, $5653d4c4, $247d8b57, $8b185d8b, $108b0c45, $8bdc5589 fncode(6) = $55890450, $89c933e0, $458bfc4d, $1c453bfc, $00ca8d0f, $558b0000 fncode(12) = $890a8b10, $4a8bd44d, $d84d8904, $753bf633, $978d0f20, $33000000 fncode(18) = $ec4589c0, $33f04589, $e45589d2, $33e85589, $3bc933d2, $8b5d7ed9 fncode(24) = $4589ec45, $f0458bf4, $ddf84589, $4ddcec45, $e445ddec, $dee44ddc fncode(30) = $dc45dce9, $d9ec5ddd, $00010405, $f44ddc00, $dce44ddc, $5dddd445 fncode(36) = $ec45dde4, $ddec4ddc, $4ddce445, $d8c1dee4, $0001081d, $9ee0df00 fncode(42) = $c18b0d76, $99286df7, $148bfbf7, $4105eb87, $a37fd93b, $75ff5652 fncode(48) = $0875fffc, $000000e8, $14458b00, $6ddc00dd, $d45dddd4, $20753b46 fncode(54) = $ff698c0f, $4d8bffff, $dc01dd14, $5ddddc45, $fc45ffdc, $3bfc458b fncode(60) = $8c0f1c45, $ffffff36, $8b5b5e5f, $24c25de5, $00000000, $40000000 fncode(66) = $40800000 r = callfunc(prm, varptr(fncode), 9)

C言語側

#include <windows.h> void WINAPI DrawMandelbrotSet(HDC hdc, double *RealMin, double *ImagMax, double *step, int iteration, int width, int height, COLORREF *ColorTable, int LengthColorTable) { int i, x, y; double hoge, re, im, real, imag; COLORREF color; real = *RealMin; for(x = 0; x < width; x++) { imag = *ImagMax; for(y = 0; y < height; y++) { re = 0.0; im = 0.0; color = RGB(0, 0, 0); for(i = 0; i < iteration; i++) { hoge = re; re = re * re - im * im + real; im = 2.0 * hoge * im + imag; if (re * re + im * im > 4.0) { color = ColorTable[i * LengthColorTable / iteration]; break; } } SetPixelV(hdc, x, y, color); imag -= *step; } real += *step; } }



この記事に返信する


suppi-

リンク

2008/8/6(Wed) 22:12:48|NO.17940

アセンブラコードでは、SetPixelV()でどこに飛ぶようになっていますか?
うまくいくかわかりませんが、HSPから渡したWinAPIの関数ポインタを使ってはどうでしょう?

; 関数ポインタ
#uselib "gdi32"
#func SetPixelV "SetPixelV"
mes varptr(SetPixelV)



YOYO

リンク

2008/8/6(Wed) 23:23:48|NO.17942

これでいいですか?
C-->マシン語にはblueleafさんのmake.exeを使ってます。

#uselib "kernel32.dll" #func VirtualProtect "VirtualProtect" var,int,int,var #define xdim(%1,%2) dim %1,%2: VirtualProtect %1,%2*4,$40,AZSD #uselib "gdi32" #func SetPixelV "SetPixelV" dim ColorTable, 191 repeat 191 hsvcolor cnt, 255, 255 ColorTable(cnt) = ginfo_r + (ginfo_g << 8) + (ginfo_b << 16) loop RealMin = -2.0 ImagMax = 1.25 step = 0.0052083333333333333333333333333333 dim prm,14 prm.0 = hdc prm.1 = varptr(RealMin) prm.2 = varptr(ImagMax) prm.3 = varptr(step) prm.4 = 128 prm.5 = 480 prm.6 = 480 prm.7 = varptr(ColorTable) prm.8 = length(ColorTable) prm.9 = varptr(SetPixelV) dupptr prm2,varptr(prm.10),16,vartype("double") prm2.0= 2.0 prm2.1= 4.0 xdim fncode,63 fncode.0=$83ec8b55,$c933d4c4,$8b575653,$7d8b0c45,$185d8b24,$5589108b,$04508bdc,$89e05589 fncode.8=$458bfc4d,$1c453bfc,$00c48d0f,$558b0000,$890a8b10,$4a8bd44d,$d84d8904,$753bf633 fncode.16=$918d0f20,$33000000,$89d233c0,$4589ec45,$e45589f0,$33e85589,$3bc933d2,$8b577ed9 fncode.24=$4589ec45,$f0458bf4,$ddf84589,$4ddcec45,$e445ddec,$dee44ddc,$dc45dce9,$ddec5ddd fncode.32=$4ddc3045,$e44ddcf4,$ddd445dc,$45dde45d,$ec4ddcec,$dce445dd,$c1dee44d,$df385ddc fncode.40=$0d769ee0,$6df7c18b,$fbf79928,$eb87148b,$d93b4105,$5652a97f,$50fc458b,$51084d8b fncode.48=$8b2c55ff,$dd461445,$d46ddc00,$3bd45ddd,$8c0f2075,$ffffff6f,$dd14558b,$dc45dc02 fncode.56=$ffdc5ddd,$4d8bfc45,$1c4d3bfc,$ff3c8c0f,$5e5fffff,$5de58b5b,$000038c2 r = callfunc(prm, varptr(fncode), 14) redraw 1
C言語側

#include <windows.h> void WINAPI DrawMandelbrotSet(HDC hdc, double *RealMin, double *ImagMax, double *step, int iteration, int width, int height, COLORREF *ColorTable, int LengthColorTable,BOOL (WINAPI *SetPixelV)(HDC,int,int,COLORREF),double d1,double d2) { int i, x, y; double hoge, re, im, real, imag; COLORREF color; real = *RealMin; for(x = 0; x < width; x++) { imag = *ImagMax; for(y = 0; y < height; y++) { re = 0.0; im = 0.0; color = RGB(0, 0, 0); for(i = 0; i < iteration; i++) { hoge = re; re = re * re - im * im + real; im = d1 * hoge * im + imag; if (re * re + im * im > d2) { color = ColorTable[i * LengthColorTable / iteration]; break; } } SetPixelV(hdc, x, y, color); imag -= *step; } real += *step; } }



なたで

リンク

2008/8/6(Wed) 23:49:03|NO.17943

もう解決していますが、WindowsAPIを使用しないバージョンを作ってみました。

HSP

#uselib "kernel32.dll" #func VirtualProtect "VirtualProtect" var,int,int,var #define xdim(%1,%2) dim %1,%2: VirtualProtect %1,%2*4,$40,AZSD dim ColorTable, 191 repeat 191 hsvcolor cnt, 255, 255 ColorTable(cnt) = ginfo_r + (ginfo_g << 8) + (ginfo_b << 16) loop RealMin = -2.0 ImagMax = 1.25 step = 0.0052083333333333333333333333333333 f = 4.0 xdim codepset, 17 codepset( 0) = $04244c8b, $8b08418b, $498b1451, $24442b04, $4148530c, $8303c96b codepset( 6) = $af0ffce1, $244c8bc1, $03c96b0c, $4c8bc103, $d98b1424, $8810fbc1 codepset(12) = $448d101c, $d18b0110, $8808fac1, $01488810, $0000c35b mref bmscr,67 prm.0 = varptr(bmscr) prm.1 = varptr(RealMin) prm.2 = varptr(ImagMax) prm.3 = varptr(step) prm.4 = 128 prm.5 = 480 prm.6 = 480 prm.7 = varptr(ColorTable) prm.8 = length(ColorTable) prm.9 = varptr(f) prm.10 = varptr(codepset) xdim codefn, 52 codefn( 0) = $83ec8b55, $458b10ec, $5300dd0c, $5ddddb33, $1c5d39f0, $00b38e0f codefn( 6) = $8b560000, $8b571475, $00dd1045, $7d39ff33, $f85ddd20, $00878e0f codefn(12) = $eed90000, $c933d233, $5539c0d9, $7ec1d918, $dec2d954, $ebc2d9cb codefn(18) = $d9c9d908, $d9cad9cb, $8be3dec9, $cad92c45, $d9f045dc, $d9cadec9 codefn(24) = $dcc0dcc9, $c0d9f845, $c2d9c9d8, $c1d9cbd8, $18dcc1d8, $c4f6e0df codefn(30) = $42087441, $7c18553b, $8b10ebc8, $45af0fc2, $7df79928, $244d8b18 codefn(36) = $dd810c8b, $d9dd51db, $53d8dd57, $75ffd8dd, $3055ff08, $dcf845dd codefn(42) = $10c48326, $207d3b47, $0ff85ddd, $ffff798c, $f045ddff, $1c5d3b43 codefn(48) = $5ddd06dc, $548c0ff0, $5fffffff, $c3c95b5e r = callfunc(prm, varptr(codefn), 11) redraw 1

fn

void DrawMandelbrotSet(int bmscr, double *RealMin, double *ImagMax, double *step, int iteration, int width, int height, int *ColorTable, int LengthColorTable , double *f , int (*pset)(int bmscr,int X,int Y,int crColor)) { int i, x, y; double hoge, re, im, real, imag; int color; real = *RealMin; for(x = 0; x < width; x++) { imag = *ImagMax; for(y = 0; y < height; y++) { re = 0.0; im = 0.0; color = 0; for(i = 0; i < iteration; i++) { hoge = re; re = re * re - im * im + real; im = hoge * im * 2 + imag; if (re * re + im * im > *f) { color = ColorTable[i * LengthColorTable / iteration]; break; } } pset(bmscr, x, y, color); imag -= *step; } real += *step; } }

pset

void pset (int *BMSCR,int x,int y,int color) { unsigned char *DIB; int w; DIB = (unsigned char *)BMSCR[5]; w = BMSCR[1]*3+3&~3; w = w * (BMSCR[2]-y-1) + x*3; DIB[w++] = (color>>16)&0xff; DIB[w++] = (color>>8)&0xff; DIB[w] = color&0xff; }



arctan

リンク

2008/8/7(Thu) 10:36:07|NO.17947

なるほど、SetPixelVのとび場所が有効ではなかったのですね。
これを参考に、ジュリア集合のプログラムも組んで見ます。
suppi-さん、YOYOさん、なたでさん、ありがとうございました。



arctan

リンク

2008/8/7(Thu) 10:36:31|NO.17948

解決を入れ忘れてました。



ash

リンク

2008/8/7(Thu) 12:16:04|NO.17953

既に解決していますが、
C言語でAPI関数を呼び出すプログラム作成した場合、それをHSPで実行するには、以下の4つ方法のどれかを使う必要があります.
#uselib "kernel32.dll"
#func Sleep "Sleep" // ① 相対アドレスで呼び出す方法 code0 = $8bec8b55,$e8500845,$00000000,$0004c2c9 lpoke code0, 8, varptr(Sleep)-(varptr(code0)+12) mes "1s 待ちます" prm = 1000 res = callfunc(prm, varptr(code0), 1) // ② アドレスを引数として渡す方法 code1 = $8bec8b55,$ff500c45,$c2c90855,$0008 mes "1s 待ちます" prm = varptr(Sleep), 1000 res = callfunc(prm, varptr(code1), 2) // ③ アドレスを直接指定する方法 code2 = $b9ec8b55,$00000000,$5008458b,$c2c9d1ff,$0004 lpoke code2, 4, varptr(Sleep) mes "1s 待ちます" prm = 1000 res = callfunc(prm, varptr(code2), 1) // ④ アドレス変数を参照させる方法 code3 = $8bec8b55,$ff500845,$00000015,$04c2c900,$00 lpoke code3, 9, varptr(ptr_Sleep) mes "1s 待ちます" prm = 1000 : ptr_Sleep = varptr(Sleep) res = callfunc(prm, varptr(code3), 1) end

① API関数を相対アドレスで呼び出す方法
 - 直接相対アドレスを書き込こむ

② API関数のアドレスを引数として渡す方法
 - 引数として関数のアドレスを送る

③ API関数のアドレスを直接コードに書き込む方法
 - 直接API関数のアドレスを書き込こむ

④ API関数のアドレスをアドレス変数として、アドレス変数を参照させる方法
 - API関数のアドレスをアドレス変数に代入し、直接アドレス変数のアドレスを書き込む

(Win32:①は相対nearコール、それ以外は絶対間接nearコール)



ONION software Copyright 1997-2025(c) All rights reserved.