标题: 请问VB调用我汇编写的函数 [打印本页] 作者: 唐明 时间: 2004-2-7 15:59 标题: 请问VB调用我汇编写的函数 我写了几个函数,VB调用后会出错,我自己汇编写的则不会1 h6 ?! b& D' v- U! H: ~1 v, A6 T
我是恢复了ESI,EDI寄存器(在WinAsm32附带的一个帮助中说要恢复,EA/B/C/DX则没有要求),老是出错(全部恢复当然就没错了).不知道他还有什么要求,知道的告诉小弟我啊!作者: hzzh 时间: 2004-2-7 19:21
你用DEBUG程序跟踪一下不就知道原因了么. y) D! [% I% f9 x8 g$ c& m3 h5 ]
既然全部恢复不出错了,就用pusha/popa好了,省事。6 R- q& [9 r& o J% ]' h+ z
对于VC程序,ECX常用于函数间传递this指针的,VB就不知道了作者: 唐明 时间: 2004-2-8 19:42
谢谢呀!作者: 水流花落 时间: 2004-3-19 17:50
转载: ) w4 d( A ]6 A/ r来教你如何在vb里嵌入汇编!6 ~) f2 q U' L1 G) _1 {0 n6 [9 ~
作者: wl3000wl ( m: j5 i$ ?0 e0 U# z8 W本贴绝对值得你珍藏. 8 i. `' _9 ^5 }, }" u6 s下面的例子完全用VB进行ASM编程的示例,本例获得CPU ID. . V5 N/ z+ f% `, m9 V5 s8 T, r- @9 b工程文件分为一个form1.frm 和一个模块module1.bas) V; ^( f) H7 e5 q4 n3 L- a
----------------------form1.frm的源文件--------------------- / K2 z. h$ | l/ OVERSION 5.00/ R! l. ^. g# S7 ~
Begin VB.Form Form1 $ _( m: a' v# I9 \
Caption = "Form1" / O4 m: r! m* \8 n8 { ClientHeight = 1965 ' T# {, d% H1 K1 p. F ClientLeft = 60* T, e8 R& S4 L5 |3 f4 k
ClientTop = 345 ! O! R4 O9 p7 ~* C, J1 |0 a ClientWidth = 3105 ; m1 g4 y/ t6 e: W" J4 @ LinkTopic = "Form1"( c1 t7 v$ y" |6 x/ H
ScaleHeight = 1965 6 ^4 M$ ?' L: Y. |" ]$ F5 g ScaleWidth = 3105 0 X: r1 Q* f+ ], J# V' k StartUpPosition = 2 'Bildschirmmitte5 Q/ e9 S( T8 D7 |- ?2 e# F" W( o
Begin VB.CommandButton Command1 5 x4 a, u, I+ m# t/ Q$ M Caption = "Get CPU Name" p) p7 z5 b2 o k& T) p5 O) r
Height = 495 ) j- N+ Q: x% F: J; u+ G. J6 O7 l Left = 840 % H& G4 V+ |' D! x4 v TabIndex = 0 0 R3 W' h/ [ g! o Top = 315 5 \7 X( N6 J2 M1 _ Width = 1425 # b. ]% X4 r5 Q7 O$ C/ v% b End " u+ a G' {- P1 _7 F7 u Begin VB.Label Label2 / R3 ]- G, F$ h6 N
Alignment = 2 'Zentriert 9 K% {# Y! f- o- \6 c$ s AutoSize = -1 'True4 W/ ~# Z4 Q1 U1 [! p. y
BeginProperty Font - b8 _. J0 d; U8 s
Name = "MS Sans Serif"9 k4 h) n' G) N, b; F( D* }
Size = 9.759 B: J( M9 I* _. [: z* q4 p
Charset = 0$ n k0 p5 P% Z/ Y! l/ ]
Weight = 400$ i3 h( ~' U" n" m6 L; w, C" Y" w
Underline = 0 'False 6 G& {# v& [# i8 l# V: I/ o" S Italic = 0 'False , S( F5 U) q( d' V% B* ~ Strikethrough = 0 'False2 H' g9 w8 L+ D
EndProperty$ C" L% x5 R4 O$ M# f3 k6 o( l
Height = 2403 N; X$ z$ j' c! S7 T2 f, O6 I
Left = 1515& N0 s* D* P* F! o' ]1 Y! D- x# p9 X
TabIndex = 2 2 h. a; _4 |, U' p Top = 10651 b$ F3 t* j* r- n& i! ^
Width = 60 ! I: Z1 t( r/ T+ r! D* Y& V; J End / P# ]) B; [- I) V9 |3 L2 b Begin VB.Label Label1 : m9 e% @" H3 w Alignment = 2 'Zentriert o+ C2 K0 g* e AutoSize = -1 'True+ V6 b3 _3 V* n2 l
BeginProperty Font - K- v3 l1 ~% ~0 B5 T Name = "Arial" 3 z) c- g/ ]0 v7 W2 z, h Size = 12, b4 m) I/ c3 n% w- O9 _1 e; p6 ~
Charset = 0 8 T# W% z1 [6 _5 ] Weight = 700 + @: _' Q, F! A$ s" d. S R6 _ Underline = 0 'False 7 C2 N9 {/ \* i2 l& R3 B, @ Italic = 0 'False; ]& c2 g! j# N1 `* h) k: M2 |
Strikethrough = 0 'False & d, [( h, q& o: Q$ [. u EndProperty " t3 i& [8 Y* [5 k* Y+ U9 W8 V Height = 285 6 M9 V6 G! m9 ~( S9 R' ^3 p% c. { Left = 1515$ G% A' Q& u' j, A+ \ K
TabIndex = 1 2 Q6 ]* r( n* n1 N$ [/ x# r" _ Top = 1350/ X$ S" K* P: Y t% ~0 c
Width = 75 9 K; S/ Q5 \) Q& I End7 O+ v4 B1 W& \2 ]' V3 E( J
End+ O9 @+ E6 ?1 C
Attribute VB_Name = "Form1"' ~% T# H: y X; q, S ?1 B* l* s
Attribute VB_GlobalNameSpace = False& B8 |! d4 ^1 |! y( e7 J
Attribute VB_Creatable = False # G* p1 K9 j, NAttribute VB_PredeclaredId = True7 S4 V/ A7 F7 T& r/ U; ~9 B& ]
Attribute VB_Exposed = False; w8 O( q/ B3 {8 z
Option Explicit / `5 W3 Q/ P5 L" l( {/ s! B ) P) w% G: n0 h& P4 a! P2 ^' yPrivate Sub Command1_MouseDown(Button As Integer, Shift As Integer, x As Single, Y As Single) 1 m/ x3 \# k5 {& I r- Q) X$ a! A: |
Label1 = ""+ J# r K" g# w7 l7 `2 Y
Label2 = "". z! ?8 R: f8 Z1 c
2 j# {" Y- i& D, ~) {+ {End Sub 3 M% g% B& e8 q9 u/ u+ J7 F$ m7 s' ]
Private Sub Command1_Click()3 W; n/ K! P4 Z2 B. d3 s Z% m
3 ]+ w9 n$ C/ \. @; ^7 N
Label1 = GetCpuName() & " CPU"# _1 z' l3 K1 R _: R
Label2 = "You have a" & IIf(InStr("AEIOU", Left$(Label1, 1)), "n", "") # H" Y9 G" i5 k. z( O: X; k, p* d ) d2 i* D$ ?$ n$ q$ CEnd Sub+ `( t+ D; g( W
------------------------------end--------------------------------- 5 m9 c: P* b2 Q) @0 P1 H K! x& | / i& N" q% S2 Y* l9 A! G/ b$ B/ `* i& k0 [- ]( Q
; L3 r& Z9 B P, F) k: d' X+ |6 l5 V . R, ]$ A+ {0 k2 \: @: f& N0 G5 e, X q
下面是modu1e.bas的源代码+ S3 R2 L0 I2 M$ ^8 M4 f& P* S
8 P% P) a; P: ~' C6 u$ u' ?' `
----------------------module1.bas的源文件-------------------------- 9 l2 l4 k. m6 _# _( F V9 z* uOption Explicit7 J; d6 i- @ ~ i$ b$ L
' 7 _0 N( s1 j* Q$ p7 E% t'This shows how to incorporate machine code into VB . F' Y# {8 [1 m5 R% o D5 F0 u'''''''''''''''''''''''''''''''''''''''''''''''''''/ v- c1 l2 c7 }, ^; a( w- X
'The example fills the array with a few machine instructions and then copies! v3 y0 D( x' K& O
'them to a procedure address. The modified procedure is then called thru 6 q* h( g, [5 J7 ], g6 F, O, H# l'CallWindowProc. The result of this specific machine code is your CPU Vendor Name. B! D& i) u/ L {
' / w8 R- v) K$ V" W1 i/ g6 N'########################################################################## ! R4 m4 x8 p3 [8 l4 S$ M'Apparently it gets a Stack Pointer Error, but I don't know why; if anybody- f1 G- s: I& t2 i q% S3 H
'can fix that please let me know... UMGEDV@AOL.COM . A; m4 H4 E% C% I'The Error is not present in the native compiled version; so I think it got, D( C3 p9 p) Q/ @
'something to do with the P-Code Calling Convention (strange though)... 2 ?% \$ o( }( ~0 B: e. T'##########################################################################* H& f; L7 \% h& r
'( @4 b: z+ j$ R: n1 o! v
'Sub Dummy serves to reserve some space to copy the machine instructions into.0 K" } [# J* ?) _/ D! ?. U
' - [' i6 O& K/ V$ ]': a- l4 m( b& B
'Tested on Intel and AMD CPU's (uncompiled and compiled) l; M8 n6 w* l5 C# G& J+ z& g'9 W" m% |3 z1 j8 o1 U
' " A( |' q( [* U, P2 JPrivate Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long7 [9 E r j. c
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long) * w. h0 |! G" X2 g0 fPrivate x As Long/ \# t7 p# F- x
6 @3 z8 B0 V" v O# m$ s6 mPublic Function GetCpuName() As String ) F4 H. S4 l0 S 4 l/ L7 H- }- @$ A6 X+ E
Dim MachineCode(0 To 35) As Byte # W" ^: ]! d( | Dim VarAddr As Long 6 f0 @/ P" u7 }0 Z2 F- l Dim FunctAddr As Long 8 c) L& H( Q- S- z- x, c Dim EAX As Long1 l& N7 B/ X9 G# p! H- t
Dim CPUName(1 To 12) As Byte1 L3 K% |. U0 i& G& B5 j; F
% ?+ W* I* m6 o9 g- `6 w, B% E% a
'set up machine code 3 d; [/ F! t3 c) K + Q5 _, _, [5 Y+ G) j0 L
MachineCode(0) = &H55 'push ebp( I0 _% |% M5 E5 O% L; E
/ E U; f3 Q$ [7 D MachineCode(1) = &H8B 'move ebp,esp # i0 \) u! n+ w: x6 f MachineCode(2) = &HEC" h1 [# R6 M: W# K0 w8 m x$ Y
% _$ k; s; s- k+ q: }8 @
MachineCode(3) = &H57 'push edi0 M) l6 d* G. e2 c
1 R4 b7 b0 i e. X
MachineCode(4) = &H52 'push edx 5 S; K9 C. v3 Y6 O0 K ) O( k4 c1 W! Z/ z1 M* Y1 z3 s" S) U; Q4 ^; ]
MachineCode(5) = &H51 'push ecx 7 Z: v% i! O8 J- {; A2 U, v % v: Q, c: f$ A& M4 L/ f MachineCode(6) = &H53 'push ebx 0 C: B2 o8 h/ h8 w- a- Q& o ) Q6 n; t/ {' ^. f3 G1 t8 g S. C MachineCode(7) = &H8B 'move eax,dword ptr [ebp+8] ) k t0 ]4 x. x0 f MachineCode(8) = &H450 P; J! N+ Z' v# {7 z$ ~, Z& @3 T
MachineCode(9) = &H8 * l5 ]3 Y- K/ J8 j* E" m ( B* L+ X( d, x9 V8 g1 B( j
MachineCode(10) = &HF 'cpuid# D3 [0 `+ ~. D
MachineCode(11) = &HA2 ' }) Q6 H; }- J$ @, s 3 A$ {7 y7 @( V! U- z2 t. ]+ U( N MachineCode(12) = &H8B 'mov edi,dword ptr [ebp+12]/ f. z7 q+ [; f+ P7 H
MachineCode(13) = &H7D1 P5 H/ B7 ?' r8 a7 u/ I; P# Y
MachineCode(14) = &HC$ u- E' B8 b$ i- Y" W: K5 d4 X% `
# [; ]% j, I# z1 ]. S MachineCode(15) = &H89 'move dword ptr [edi],ebx1 T# g6 w5 M I6 K8 C4 @2 ~" O
MachineCode(16) = &H1F , l1 f- N! l+ z9 y9 ] ( l- T; R+ v A- ~; z3 }
MachineCode(17) = &H8B 'mov edi,dword ptr [ebp+16] 6 X& S% s0 v2 {0 L MachineCode(18) = &H7D . J7 N' i. M9 T# }; K1 z" E MachineCode(19) = &H10# t5 J. f0 v, V
' `. r% U/ i& S3 k0 X
MachineCode(20) = &H89 'move dword ptr [edi],ecx; J' [3 m3 `' P) w. M9 j
MachineCode(21) = &HF4 l" U( ]0 S4 c' V2 ^* T2 ?
, u3 _( X+ B. d! J5 ^* e
MachineCode(22) = &H8B 'mov edi,dword ptr [ebp+20] 9 v2 K1 i8 X, r* |, Z MachineCode(23) = &H7D - W8 A4 Q a6 }4 ]6 o MachineCode(24) = &H14 7 N6 F m, G) \- B. `2 r , D5 E1 a5 d1 u0 W8 M( i/ A( C MachineCode(25) = &H89 'move dword ptr [edi],edx0 d! J i( h& r3 H/ g- c/ f0 \
MachineCode(26) = &H174 u/ E& z) K7 ]) W* G
5 G9 s" M; \4 ]
MachineCode(27) = &H58 'pop ebx2 e1 z8 g5 I$ E/ Q
8 j0 @* @9 v# Y" f MachineCode(28) = &H59 'pop ecx & N' z: L( H T# x* S/ ?1 n n7 s! C% L
MachineCode(29) = &H5A 'pop edx ' u& w, T) k! t. B1 w& g0 [ + ^( a6 C8 }3 @2 n MachineCode(30) = &H55 'pop edi & B" j: x! O( i1 X' D ! [: K% M+ F2 m) m7 _7 }- H% _$ ^
MachineCode(31) = &HC9 'leave B8 K9 N% ?4 M- J' p* y# N( B1 T7 w# ?0 }7 k- V- |
MachineCode(32) = &HC2 'ret 16 I tried everything from 0 to 249 p5 N5 ?* q: U( ]* m1 D
MachineCode(33) = &H10 ' but all produce the stack error ! U& M `0 y# j9 x2 _ MachineCode(34) = &H0 ) x- r. W+ M9 z8 _1 L/ P8 K8 a- \ , O& Y, Y$ o' p0 d7 _! p 'tell cpuid what we want# }: k J' |8 c3 f: A; o4 m' B, V
EAX = 0 b* ~4 y7 f! m3 Z% n& d. \ . o" x9 W, B6 t2 I, |( g
'get address of Machine Code 5 y- U J: \: `8 I( A8 A) h8 V* o2 V% [+ B VarAddr = VarPtr(MachineCode(0)): M" b* k" o0 V5 N0 k% f
1 W6 Y- E0 r0 x8 T" j* | 'get address of Sub Dummy) V5 n5 v. o: P9 o9 q
FunctAddr = GetAddress(AddressOf Dummy) ' n9 S0 w8 F2 V+ p: S$ S! ^ , V' x& j) Q7 [ 'copy the Machine Code to where it can be called$ l4 T) j6 E2 ^# |/ X' J) G& \
CopyMemory ByVal FunctAddr, ByVal VarAddr, 35 '35 bytes machine code' H) }" \+ c% U: n, S0 Y3 z- b
0 D4 G# |7 M* L6 N; {5 L 'call it* ]6 M8 c a4 K8 [. Y
On Error Resume Next 'apparently it gets a stack pointer error when in P-Code but i dont know why - B9 k* F- G3 K2 j$ H+ u, Z1 @# B CallWindowProc FunctAddr, EAX, VarPtr(CPUName(1)), VarPtr(CPUName(9)), VarPtr(CPUName(5)) / C8 N# C0 H# D' n4 z9 p3 L 'Debug.Print Err; Err.Description 8 W; [- i! {( w 'MsgBox Err & Err.Description * o5 d( |8 O y- \ On Error GoTo 0 8 ~7 O) Q' [3 F ! a$ F& p4 C, P" I6 _) Y GetCpuName = StrConv(CPUName(), vbUnicode) 'UnicodeName 9 B; h0 u0 H6 q( e/ d : \- J0 R r9 c* X! O
End Function & \' @& W) {+ a4 U# \6 ]( [! M $ E9 c3 E8 N- Q6 w& m" ~Private Function GetAddress(Address As Long) As Long, h9 |: [; f w/ i
( V7 m/ G6 [; N) T4 h GetAddress = Address D7 a2 V. r3 u& Q2 Y* e g$ [; E( Z% LEnd Function8 F4 U0 j% B' r+ }; R, }9 _
& F2 q+ g* m: L! N( I) e" dPrivate Sub Dummy()9 P5 A8 ]: B( i' H
8 F. g% x: T( Y: z( Z! }, B7 {( d2 f
'the code below just reserves some space to copy the machine code into " X2 w( b6 _$ O- { 'it is never executed / f& y' p( ^! U. J" ^1 \( [& N. l$ b! @1 y v3 ^7 y* r
x = 0 7 }$ Y) G3 g' b% j9 w! `/ K x = 1 }% K6 A- c( w, v& N# k6 o
x = 25 c1 l9 Z+ N8 p
x = 3 ' f3 _2 R5 X! u+ ~; {( J" f0 o/ ^: m x = 49 k; w. o) j" |% _; r( v
x = 5& d2 d2 v& \% H
x = 6( r Z6 Q$ E. m* c5 @7 Y A
x = 7! `2 D1 H2 N( t n7 l, M
x = 8 0 t0 P! f9 D/ u* G7 B; \* g x = 9, P5 @. c5 F/ L3 r5 J
x = 100 j4 w% p x1 a o& U+ z2 O# N6 G2 U
x = 0 , @9 R7 J4 I: I! A4 i, L x = 1 ; h& a4 \/ J6 W& ?, ]; t/ O6 o8 r! D x = 2 . l- T3 R3 ?0 Y4 C+ \) b" F. `( W x = 3- `# s4 s) i f4 _) c& k
x = 41 R D& R, M0 x# r
x = 55 n( X& h; }5 i! k# P1 _8 V1 b
x = 6 : X0 U* {* ]. V+ I( T: _ x = 7 $ j( a- V8 K) q3 t x = 8 v4 V" l( S: V7 c
x = 9 : E O' ~+ @2 ^; R+ | x = 10+ ?+ u$ y1 O: w% d3 O" {1 d
: k/ S% K( f# [% B
End Sub. _+ w/ O3 t+ @8 G/ B1 q. ~0 m
------------------------------end-------------------------------------- * @# k5 S! s) R: R 5 C* @; V# w1 p# X) v7 f - F+ \( g" S: z$ t' q I9 b $ X$ t6 [$ t. f