Home > Archive > A86 Assembler > April 2005 > new from VB6
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| mayayana 2005-04-21, 8:55 pm |
| Could someone point me in the right
direction for *very basic" beginner information?
I'm coming from VB6, with experience in
terms of Win32 API, dealing with memory
addresses, data types, and that sort of
thing. But I've never learned the real basics.
I thought that maybe learning ASM would
be a good way to do that. I've also used some
inline assembly in VB and can see that it has
a lot of potential.
I just bought Randy Hyde's book, Art of Assembly
Language. I've also looked at the FAQ. But it
all assumes prior knowledge. On p. 9 of Randy's
book he describes the "registers", but never explains
what a "register" actually is. Likewise, I really don't
understand stack and heap. I'm coming from the
top down and seem to have missed out on learning
something critical at ground level. I can understand
something like mov as being similar to
RTLMoveMemory, but don't understand the mechanics
at this level.
_____________________________
mayayXXana1a@mindYYspring.com
For return email remove XX and YY.
_____________________________
| |
| randyhyde@earthlink.net 2005-04-22, 3:55 am |
| You might want to consider taking "AoA" back and getting a copy of my
book "Write Great Code, Volume I, Understanding the Machine". It sounds
like this would be a better fit for your needs.
Cheers,
Randy Hyde
| |
| Jim Carlock 2005-04-22, 3:55 am |
| I think one of the easiest ways to really start out is to start
with a simple DOS program.
Here's the first program. The stuff below... the - (dash) is the
debug.exe prompt (similar to the c: prompt for the DOS command
line). It means debug is waiting for you to enter a command. The
list of available commands can be seen by typing a question mark
at a dash and then pressing the Enter key.
Any line that starts with a semicolon represents my own comments.
Do NOT type in those lines. They are just explanatory things. I'm
using the ; character because it's the character used inside of
various assemblers to indicate a comment.
At a DOS prompt type in the following:
; We start out at the DOS command prompt and are going to use DEBUG
; to create a simple program that displays some text inside the DOS
; command prompt.
C:\temp\>debug test.com
File not found
; The dash is the debug prompt, don't type it in, type in the command after
; it. rcx tells debug you want to see and edit the contents of the CX register.
- rcx
CX 0000
; debug displays the current contents of the CX register above and then
; waits for you to type a number in. The number is the size of the file we
; are creating. The size for this program is 118 bytes in length.
118
-a 100
mov ah, 09
mov dx, 109
int 21
int 20
a 109 db 'Hello world.' 0d 0a 24
w
q
C:\>
Now for a brief explanation of what's going on...
r is debug's command to display registers. The registers are
rcx is the command to get debug to show you and allow you to modify
the contents of the register.
a 100 tells debug you want to start typing assembly language at
address 100. DEBUG then waits for you to start typing assembly
mnemonics.
The mnemonics are those assembly language commands you entered
starting at address 0100. ALL .com programs start at that there
at that address.
We use the rcx command to configure the size of the file. The
w command (write to file) tells DEBUG to save the file and the
CX register inside of the CPU holds the number (the size).
There are 4 registers inside of the CPU that folks primarily
use. EAX (the 32-bit register), EBX, ECX and EDX. We used the
16-bit register AX to store a number (09). That particular
register stores what is called the Interrupt number (we used
DOS Interrupt 21, Function 9). The DX register holds the other
information required for Interrupt 21. Interrupt 21, Function 9
is the simplest Interrupt I could think of that doesn't require
too much effort to get you up to speed with what the registers
do.
One other important register, is the EIP (Instruction Pointer)
register. This register tracks the memory address of the
currently executing instruction. If you were to step through
the Test.com program you created, after you type R at the debug
prompt, you'll see that the EIP/IP register increments itself
and points to the next instruction to be executed.
The processor itself is a set of chips that mean nothing to us.
However, there needs to be a way to move things around in the
processor and memory and the disk. The registers take care of
these things.
The EAX/AX register is typically called the Accumulator and
all it is is just a temporary storage facility for the CPU.
The EBX/BX register is called a Base register. It has other
uses, usually used to hold pointers to string information,
as an index to arrays, and a few other things.
The ECX/CX register is usually used to hold a count in for
next loops.
The EDX/DX register is called a Data Register. It typically
holds pointers to strings, pointers to structures, etc.
Registers are just storage locations inside of a CPU used to
count, hold pointers to strings and structures, hold source
and destination operands for various instructions.
The Interrupt instruction is a DOS command and there are a
ton of DOS Interrupt functions. We used Function 9 which
simply displays a "$" dollar sign terminated string to the
console. The AX register holds the Function number when calling
Interrupt 21. The DX register holds the pointer to the string
we want displayed. Character code 24 is the ASCII number for
the "$" dollar sign symbol. 0D 0A is the CRLF combination to
start a new line.
There are more registers used for different things such as the
math coprocessor registers and some others.
As far as the stack goes, that is just an area of memory that
holds parameters for functions. When a subroutine is called,
the parameters for the subroutine get pushed onto the stack,
and when the subroutine returns, the parameters are popped off
the stack.
It's really a big topic to cover because there are quite a few registers
out there and I've only touched on 5 of them.
If something is puzzling feel free to ask. Hope that helps.
--
Jim Carlock
Please post replies to newsgroup.
"mayayana" <spamtrap@crayne.org> wrote:
Could someone point me in the right
direction for *very basic" beginner information?
I'm coming from VB6, with experience in
terms of Win32 API, dealing with memory
addresses, data types, and that sort of
thing. But I've never learned the real basics.
I thought that maybe learning ASM would
be a good way to do that. I've also used some
inline assembly in VB and can see that it has
a lot of potential.
I just bought Randy Hyde's book, Art of Assembly
Language. I've also looked at the FAQ. But it
all assumes prior knowledge. On p. 9 of Randy's
book he describes the "registers", but never explains
what a "register" actually is. Likewise, I really don't
understand stack and heap. I'm coming from the
top down and seem to have missed out on learning
something critical at ground level. I can understand
something like mov as being similar to
RTLMoveMemory, but don't understand the mechanics
at this level.
_____________________________
mayayXXana1a@mindYYspring.com
For return email remove XX and YY.
_____________________________
| |
| mayayana 2005-04-22, 3:55 am |
| Now ya tell me. :)
Thanks. I'll keep that in mind, although there wasn't much
available when I went looking, and AoA was the only copy
of yours. In fact the onsite computer (Boston University
bookstore, Boston MA) didn't list any other books by you,
much less carry them.
> You might want to consider taking "AoA" back and getting a copy of my
> book "Write Great Code, Volume I, Understanding the Machine". It sounds
> like this would be a better fit for your needs.
> Cheers,
> Randy Hyde
>
| |
| spamtrap@crayne.org 2005-04-22, 8:55 am |
|
mayayana wrote:
> Could someone point me in the right
> direction for *very basic" beginner information?
> I'm coming from VB6, with experience in
> terms of Win32 API, dealing with memory
> addresses, data types, and that sort of
> thing. But I've never learned the real basics.
>
>
> I thought that maybe learning ASM would
> be a good way to do that. I've also used some
> inline assembly in VB and can see that it has
> a lot of potential.
I didn't know you could use inline assembler
in VB? How is that done?
-John
| |
| mayayana 2005-04-22, 3:56 pm |
| Thanks, Jim. (You seem to be in all the newsgroups!)
That does clear some things up. So registers are
variable/value storage that bypasses the RAM and
goes directly to the CPU. I guess, then, that they're
just used and reused one operation at a time? And
that's why you can get by with only the equivalent of
8 4-byte addresses for general use. I don't see why
the different registers would need to be used for different
uses if they're essentially CPU memory addresses, but I'm
beginning to see the basic idea.
So the stack is essentially my own storage area that I
pile pointers or literal values onto.....and that's *always*
where the processing looks to find function parameters?
So if I were to call, say: DoIt 5, 3, 2 - where the 3
parameters are all longs - I could conceivably look at the
top 12 bytes of the stack while that's running (assuming one
can look at the stack dynamically) and find the values
5, 3, 2 there? Or in the case of a string parameter I'd
find the string pointer? So I can go as deep with the stack
as I want to, but it always clears when a function returns?
Is the heap, then, just that....a pile of memory addresses
that represent my allocated variable space?
--
_____________________________
mayayXXana1a@mindYYspring.com
For return email remove XX and YY.
_____________________________
Jim Carlock <spamtrap@crayne.org> wrote in message
news:YMZ9e.8935$716.6772@tornado.tampabay.rr.com...
> I think one of the easiest ways to really start out is to start
> with a simple DOS program.
>
> Here's the first program. The stuff below... the - (dash) is the
> debug.exe prompt (similar to the c: prompt for the DOS command
> line). It means debug is waiting for you to enter a command. The
> list of available commands can be seen by typing a question mark
> at a dash and then pressing the Enter key.
>
> Any line that starts with a semicolon represents my own comments.
> Do NOT type in those lines. They are just explanatory things. I'm
> using the ; character because it's the character used inside of
> various assemblers to indicate a comment.
>
> At a DOS prompt type in the following:
>
> ; We start out at the DOS command prompt and are going to use DEBUG
> ; to create a simple program that displays some text inside the DOS
> ; command prompt.
> C:\temp\>debug test.com
> File not found
>
> ; The dash is the debug prompt, don't type it in, type in the command
after
> ; it. rcx tells debug you want to see and edit the contents of the CX
register.
> - rcx
> CX 0000
> ; debug displays the current contents of the CX register above and then
> ; waits for you to type a number in. The number is the size of the file we
> ; are creating. The size for this program is 118 bytes in length.
> 118
> -a 100
> mov ah, 09
> mov dx, 109
> int 21
> int 20
>
> a 109 db 'Hello world.' 0d 0a 24
> w
> q
> C:\>
>
> Now for a brief explanation of what's going on...
>
> r is debug's command to display registers. The registers are
>
> rcx is the command to get debug to show you and allow you to modify
> the contents of the register.
>
> a 100 tells debug you want to start typing assembly language at
> address 100. DEBUG then waits for you to start typing assembly
> mnemonics.
>
> The mnemonics are those assembly language commands you entered
> starting at address 0100. ALL .com programs start at that there
> at that address.
>
> We use the rcx command to configure the size of the file. The
> w command (write to file) tells DEBUG to save the file and the
> CX register inside of the CPU holds the number (the size).
>
> There are 4 registers inside of the CPU that folks primarily
> use. EAX (the 32-bit register), EBX, ECX and EDX. We used the
> 16-bit register AX to store a number (09). That particular
> register stores what is called the Interrupt number (we used
> DOS Interrupt 21, Function 9). The DX register holds the other
> information required for Interrupt 21. Interrupt 21, Function 9
> is the simplest Interrupt I could think of that doesn't require
> too much effort to get you up to speed with what the registers
> do.
>
> One other important register, is the EIP (Instruction Pointer)
> register. This register tracks the memory address of the
> currently executing instruction. If you were to step through
> the Test.com program you created, after you type R at the debug
> prompt, you'll see that the EIP/IP register increments itself
> and points to the next instruction to be executed.
>
> The processor itself is a set of chips that mean nothing to us.
> However, there needs to be a way to move things around in the
> processor and memory and the disk. The registers take care of
> these things.
>
> The EAX/AX register is typically called the Accumulator and
> all it is is just a temporary storage facility for the CPU.
>
> The EBX/BX register is called a Base register. It has other
> uses, usually used to hold pointers to string information,
> as an index to arrays, and a few other things.
>
> The ECX/CX register is usually used to hold a count in for
> next loops.
>
> The EDX/DX register is called a Data Register. It typically
> holds pointers to strings, pointers to structures, etc.
>
> Registers are just storage locations inside of a CPU used to
> count, hold pointers to strings and structures, hold source
> and destination operands for various instructions.
>
> The Interrupt instruction is a DOS command and there are a
> ton of DOS Interrupt functions. We used Function 9 which
> simply displays a "$" dollar sign terminated string to the
> console. The AX register holds the Function number when calling
> Interrupt 21. The DX register holds the pointer to the string
> we want displayed. Character code 24 is the ASCII number for
> the "$" dollar sign symbol. 0D 0A is the CRLF combination to
> start a new line.
>
> There are more registers used for different things such as the
> math coprocessor registers and some others.
>
> As far as the stack goes, that is just an area of memory that
> holds parameters for functions. When a subroutine is called,
> the parameters for the subroutine get pushed onto the stack,
> and when the subroutine returns, the parameters are popped off
> the stack.
>
> It's really a big topic to cover because there are quite a few registers
> out there and I've only touched on 5 of them.
>
> If something is puzzling feel free to ask. Hope that helps.
>
> --
> Jim Carlock
> Please post replies to newsgroup.
>
> "mayayana" <spamtrap@crayne.org> wrote:
> Could someone point me in the right
> direction for *very basic" beginner information?
> I'm coming from VB6, with experience in
> terms of Win32 API, dealing with memory
> addresses, data types, and that sort of
> thing. But I've never learned the real basics.
>
> I thought that maybe learning ASM would
> be a good way to do that. I've also used some
> inline assembly in VB and can see that it has
> a lot of potential.
>
> I just bought Randy Hyde's book, Art of Assembly
> Language. I've also looked at the FAQ. But it
> all assumes prior knowledge. On p. 9 of Randy's
> book he describes the "registers", but never explains
> what a "register" actually is. Likewise, I really don't
> understand stack and heap. I'm coming from the
> top down and seem to have missed out on learning
> something critical at ground level. I can understand
> something like mov as being similar to
> RTLMoveMemory, but don't understand the mechanics
> at this level.
> _____________________________
>
> mayayXXana1a@mindYYspring.com
> For return email remove XX and YY.
> _____________________________
>
>
| |
| mayayana 2005-04-22, 3:56 pm |
|
>
> I didn't know you could use inline assembler
> in VB? How is that done?
>
I only half understand it. That's part of why I'm here.
Matthew Curland, in his book Advanced Visual
Basic 6, explains the details, somewhat, and details
the use of the C++ VS editor to pick out the actual
instruction bytes of a function. He then puts those
numeric values into an array to create a VB function
with assembly efficiency and flexibility.
I'm not entirely clear about how he's making the
connection. He seems to be creating a sort of
fake COM object, with a dynamically-created vTable,
which provides a way to assign function addresses. Then
when one of the functions is called it runs his collection
of assembly bytes.
Curland's method turns out to be very useful
for using owner-drawn controls. He uses it to provide
a way to push back the parameters of a subclassing
sub by 4 bytes in order to squeeze in an object pointer.
The result is that you can call a subclass from within
a UserControl and send the WindowProc pointer back
inside the control - so that the UC is subclassing
itself and becomes a self-contained unit. Each UC
can subclass itself (and its "children") at initialization
and unhook at termination. His method makes owner-
drawn controls almost as easy to use as OCXs (as long
as you can avoid ending the program abruptly in
design time testing).
There's also a DLL with Curland's book and an
equivalent VB BAS module that constitutes a VB version
of the DLL. The BAS uses assembly bytes to do things
like create a very fast 4-byte CopyMemory-type function.
| |
| spamtrap@crayne.org 2005-04-22, 8:55 pm |
|
mayayana wrote:
> Thanks, Jim. (You seem to be in all the newsgroups!)
>That does clear some things up. So registers are
>variable/value storage that bypasses the RAM and
>goes directly to the CPU. I guess, then, that they're
>just used and reused one operation at a time? And
>that's why you can get by with only the equivalent of
>8 4-byte addresses for general use. I don't see why
>the different registers would need to be used for different
>uses if they're essentially CPU memory addresses, but I'm
>beginning to see the basic idea.
Different registers are used for different uses
for efficiency in the instruction codes.
The address for these registers is either implied
or encoded as bits inside the instuction.
example:
Address codes in the INC word register instuction:
AX 000 CX 001 DX 010 BX 011 SP 100 BP 101 SI 110 DI 111
The INC word instuction is 01000xxx
where xxx is the address of the cpu register to inc.
THUS 01000000 means INC AX
Where two registers are used you need two addresses.
MOV BP,BX where addresses are BX = 011 and PB = 101
The instruction code for this is,
100010 01 11 011 101
DW MOD BX BP
The D is the direction bit and the W is the size bit.
MOD = 11 means register to register
-John
| |
| mayayana 2005-04-23, 3:55 am |
| So in your example those are 16 bit addresses?
> 100010 01 11 011 101
> DW MOD BX BP
The top line is the actual bits that are being sent
in the compiled assembly to do mov BX, BP?
DW and MOD compose mov? (I don't follow what
"INC" is. Some kind of standard assignment protocol?)
I guess I'm wondering how it was that you decided
to mov between BX and BP. Just because they were
free registers at the time? Would mov AX, CX work
just as well? In other words, there seem to be somewhat
specific if flexible roles for these registers, while at the
same time they seem to be essentially equivalent variable
memory addresses.
_____________________________
mayayXXana1a@mindYYspring.com
For return email remove XX and YY.
_____________________________
<spamtrap@crayne.org> wrote in message
news:1114198981.273223.311970@f14g2000cwb.googlegroups.com...
>
> mayayana wrote:
>
>
> Different registers are used for different uses
> for efficiency in the instruction codes.
>
> The address for these registers is either implied
> or encoded as bits inside the instuction.
> example:
> Address codes in the INC word register instuction:
> AX 000 CX 001 DX 010 BX 011 SP 100 BP 101 SI 110 DI 111
> The INC word instuction is 01000xxx
> where xxx is the address of the cpu register to inc.
> THUS 01000000 means INC AX
>
> Where two registers are used you need two addresses.
> MOV BP,BX where addresses are BX = 011 and PB = 101
>
> The instruction code for this is,
> 100010 01 11 011 101
> DW MOD BX BP
>
> The D is the direction bit and the W is the size bit.
> MOD = 11 means register to register
>
>
> -John
>
| |
| spamtrap@crayne.org 2005-04-23, 3:55 pm |
|
mayayana wrote:
> So in your example those are 16 bit addresses?
They are 16 bit registers. I don't know if you
got my email on registers but EAX, AX, AH and AL
use the same set of "switches".
******** ******** ******** ********
<-------------- EAX -------------->
<------ AX ----->
<--AH--> <--AL-->
>
>
> The top line is the actual bits that are being
> sent in the compiled assembly to do mov BX, BP?
Yes, the pattern 10001001 11011101 will cause the
cpu to copy the contents of BP into BX.
> DW and MOD compose mov?
They compose part of the mov instruction (and part
of other instuctions as well). Sorry I think I just
the situation even mentioning them. You
don't have to know all that inner stuff unless you
want to write your own assembler.
> (I don't follow what "INC" is. Some kind of standard
> assignment protocol?)
It is the mnemonic for the instruction to INCrement
(add one) to a register.
> I guess I'm wondering how it was that you decided
> to mov between BX and BP. Just because they were
> free registers at the time? Would mov AX, CX work
> just as well? In other words, there seem to be
> somewhat specific if flexible roles for these
> registers, while at the same time they seem to be
> essentially equivalent variable memory addresses.
You can do some things with one register but maybe
not another register. Some complex instructions use
specific registers and assume they have been given
the correct values.
The only way to really learn all this is to write
actual programs until you "get it". I think I am
just confusing you with my "explanations" :)
Apart from Randy Hyde's online stuff you might find
Paul Carter's well written book, which he kindly made
available for download, useful to get an overview of
assembler programming and where, if anywhere, you
might like to go next.
www.drpaulcarter.com/
--
JC
| |
| Jim Carlock 2005-04-23, 3:55 pm |
| "mayayana" wrote:
> So registers are variable/value storage that bypasses the RAM and
> goes directly to the CPU.
Well, it goes like this, the registers are just areas of the microprocessor
that store values. The values are put into the registers from memory, from
hardware, and so on.
Like VB, there are sets of instructions to get things done. The instructions in
assembly language deal with moving, modifying or testing various types of
data. There is also one instruction that does nothing... NOP.
In the program demonstration I provided, if you started up debug at
the DOS prompt, you can trace through the program and view what's
happening with the registers.
One thing you'll notice is that the IP/EIP register increments itself as
step through the program. You can trace through the program with the
t command to get a feel for what's going on. DEBUG will display the
registers as it executes each command.
> I guess, then, that they're just used and reused one operation at a time?
> And that's why you can get by with only the equivalent of 8 4-byte
> addresses for general use.
Think of like it like stepping through a VB program one line at a time.
You'll need another debugger to see what's going on inside a Windows
program. OllyDebug is great for this.
http://home.t-online.de/home/Ollydbg/
What you can do is compile a small VB program with a For Next loop:
Private Sub Command1_Click()
Dim i As Long
Text1.Text = ""
For i = 1 to 5
Text1.Text = Text1.Text & QQ("Number: " & CStr(i)) & vbCrLf
Next i
End Sub
Private Function QQ(s As String, Optional sQ As String = """") As String
QQ = sQ & s & sQ
End Function
Run that through OllyDebug. There's a lot of junk you have to go through
before you actually find the Command1_Click routine, and you might
spend a day messing with it, but then you can change Command1_Click
to see what happens when you call a procedure.
Private Sub Command1_Click()
Dim i As Long
Text1.Text = ""
For i = 1 To 5
Call WriteIt(i)
Next i
End Sub
Private Sub WriteIt(i As Long)
With Text1
.Text = .Text & "Number " & QQ(CStr(i)) & vbCrLf
End With
End Sub
When I found the function by doing a search for strings (the function
name), OllyDebug seemed to think the function was data. OllyDebug
correctly inserted a With Text1 and End With but it seemed to be a
little out of place.
> I don't see why the different registers would need to be used for
> different uses if they're essentially CPU memory addresses, but
> I'm beginning to see the basic idea.
Think of them as registers, rather than memory addresses. They are
containers to hold information. Like a cash register is used to hold
different coins and dollar bills. They are a totally separate idea than
memory and it's important to make sure you when you talk about
memory you're NOT talking about registers and vice-versa. The
cash register is different than the safe but they hold the same things.
The cash register (CPU) is used constantly while the safe (memory)
is updated alot if there is alot of business going on or every so often
if there is only alittle business going on, generally speaking. :-)
> So the stack is essentially my own storage area that I pile pointers
> or literal values onto.....and that's *always* where the processing
> looks to find function parameters?
I believe that's how it works. Each program that runs gets it's own
stack that it uses. The OS operates with it's own stack. I'm hesitating
using the word *always* though.
> So if I were to call, say: DoIt 5, 3, 2 - where the 3
> parameters are all longs - I could conceivably look at the
> top 12 bytes of the stack while that's running (assuming one
> can look at the stack dynamically) and find the values
> 5, 3, 2 there?
There might be other things in there as well, depending upon the
application that compiled the program. I wouldn't depend upon
things being fixed in the stack until you've tested them out. The stack
can be used with With statements in VB to push the address of Text1
there so it can be readily used to reference Text1 (a textbox or combo-
box or whatever is used with the VB With statement).
> Is the heap, then, just that....a pile of memory addresses that
> represent my allocated variable space?
Someone else will have to answer exactly what a "heap" is in regards
to your question. I've always thought of the heap as the allocated
memory space but when I've looked up the definitions at wikipedia.org
I'm seeing a more complicated discussion of it. So I'll leave that question
for someone else to answer.
--
Jim Carlock
Please post replies to newsgroup.
| |
| mayayana 2005-04-23, 8:55 pm |
|
> I don't know if you
> got my email on registers but EAX, AX, AH and AL
> use the same set of "switches".
Yes. Was that you? I wrote back yesterday.
Thanks for this help and the book link. I also
found some fairly basic explanations in the
masm32 editor help.
> The only way to really learn all this is to write
> actual programs until you "get it". I think I am
> just confusing you with my "explanations" :)
Yes. I just wanted to be able to read the language
a bit first, so I could understand what's going on
in basic samples.
| |
| mayayana 2005-04-23, 8:55 pm |
|
>
> In the program demonstration I provided, if you started up debug at
> the DOS prompt, you can trace through the program and view what's
> happening with the registers.
>
Thanks. That sample didn't make much sense to me,
but I'll try it out. Maybe a rote task will help this click.
It's funny how that works. When I first started with programming
the most difficult concept of all was a variable. I just
couldn't see the sense of x = x +1. It took a long time
to realize that it was all based on computer architecture
rather than some kind of logical process.
| |
| spamtrap@crayne.org 2005-04-24, 8:55 am |
|
mayayana wrote:
> Could someone point me in the right
> direction for *very basic" beginner information?
> I'm coming from VB6, with experience in
> terms of Win32 API, dealing with memory
> addresses, data types, and that sort of
> thing. But I've never learned the real basics.
>
>
> I thought that maybe learning ASM would
> be a good way to do that. I've also used some
> inline assembly in VB and can see that it has
> a lot of potential.
I didn't know you could use inline assembler
in VB? How is that done?
-John
| |
| mayayana 2005-04-24, 8:55 pm |
|
>
> I didn't know you could use inline assembler
> in VB? How is that done?
>
I only half understand it. That's part of why I'm here.
Matthew Curland, in his book Advanced Visual
Basic 6, explains the details, somewhat, and details
the use of the C++ VS editor to pick out the actual
instruction bytes of a function. He then puts those
numeric values into an array to create a VB function
with assembly efficiency and flexibility.
I'm not entirely clear about how he's making the
connection. He seems to be creating a sort of
fake COM object, with a dynamically-created vTable,
which provides a way to assign function addresses. Then
when one of the functions is called it runs his collection
of assembly bytes.
Curland's method turns out to be very useful
for using owner-drawn controls. He uses it to provide
a way to push back the parameters of a subclassing
sub by 4 bytes in order to squeeze in an object pointer.
The result is that you can call a subclass from within
a UserControl and send the WindowProc pointer back
inside the control - so that the UC is subclassing
itself and becomes a self-contained unit. Each UC
can subclass itself (and its "children") at initialization
and unhook at termination. His method makes owner-
drawn controls almost as easy to use as OCXs (as long
as you can avoid ending the program abruptly in
design time testing).
There's also a DLL with Curland's book and an
equivalent VB BAS module that constitutes a VB version
of the DLL. The BAS uses assembly bytes to do things
like create a very fast 4-byte CopyMemory-type function.
| |
| spamtrap@crayne.org 2005-04-24, 8:55 pm |
|
mayayana wrote:
> Thanks, Jim. (You seem to be in all the newsgroups!)
>That does clear some things up. So registers are
>variable/value storage that bypasses the RAM and
>goes directly to the CPU. I guess, then, that they're
>just used and reused one operation at a time? And
>that's why you can get by with only the equivalent of
>8 4-byte addresses for general use. I don't see why
>the different registers would need to be used for different
>uses if they're essentially CPU memory addresses, but I'm
>beginning to see the basic idea.
Different registers are used for different uses
for efficiency in the instruction codes.
The address for these registers is either implied
or encoded as bits inside the instuction.
example:
Address codes in the INC word register instuction:
AX 000 CX 001 DX 010 BX 011 SP 100 BP 101 SI 110 DI 111
The INC word instuction is 01000xxx
where xxx is the address of the cpu register to inc.
THUS 01000000 means INC AX
Where two registers are used you need two addresses.
MOV BP,BX where addresses are BX = 011 and PB = 101
The instruction code for this is,
100010 01 11 011 101
DW MOD BX BP
The D is the direction bit and the W is the size bit.
MOD = 11 means register to register
-John
| |
| spamtrap@crayne.org 2005-04-25, 3:56 pm |
|
mayayana wrote:
> So in your example those are 16 bit addresses?
They are 16 bit registers. I don't know if you
got my email on registers but EAX, AX, AH and AL
use the same set of "switches".
******** ******** ******** ********
<-------------- EAX -------------->
<------ AX ----->
<--AH--> <--AL-->
>
>
> The top line is the actual bits that are being
> sent in the compiled assembly to do mov BX, BP?
Yes, the pattern 10001001 11011101 will cause the
cpu to copy the contents of BP into BX.
> DW and MOD compose mov?
They compose part of the mov instruction (and part
of other instuctions as well). Sorry I think I just
the situation even mentioning them. You
don't have to know all that inner stuff unless you
want to write your own assembler.
> (I don't follow what "INC" is. Some kind of standard
> assignment protocol?)
It is the mnemonic for the instruction to INCrement
(add one) to a register.
> I guess I'm wondering how it was that you decided
> to mov between BX and BP. Just because they were
> free registers at the time? Would mov AX, CX work
> just as well? In other words, there seem to be
> somewhat specific if flexible roles for these
> registers, while at the same time they seem to be
> essentially equivalent variable memory addresses.
You can do some things with one register but maybe
not another register. Some complex instructions use
specific registers and assume they have been given
the correct values.
The only way to really learn all this is to write
actual programs until you "get it". I think I am
just confusing you with my "explanations" :)
Apart from Randy Hyde's online stuff you might find
Paul Carter's well written book, which he kindly made
available for download, useful to get an overview of
assembler programming and where, if anywhere, you
might like to go next.
www.drpaulcarter.com/
--
JC
| |
| Jim Carlock 2005-04-25, 3:56 pm |
| "mayayana" wrote:
> So registers are variable/value storage that bypasses the RAM and
> goes directly to the CPU.
Well, it goes like this, the registers are just areas of the microprocessor
that store values. The values are put into the registers from memory, from
hardware, and so on.
Like VB, there are sets of instructions to get things done. The instructions in
assembly language deal with moving, modifying or testing various types of
data. There is also one instruction that does nothing... NOP.
In the program demonstration I provided, if you started up debug at
the DOS prompt, you can trace through the program and view what's
happening with the registers.
One thing you'll notice is that the IP/EIP register increments itself as
step through the program. You can trace through the program with the
t command to get a feel for what's going on. DEBUG will display the
registers as it executes each command.
> I guess, then, that they're just used and reused one operation at a time?
> And that's why you can get by with only the equivalent of 8 4-byte
> addresses for general use.
Think of like it like stepping through a VB program one line at a time.
You'll need another debugger to see what's going on inside a Windows
program. OllyDebug is great for this.
http://home.t-online.de/home/Ollydbg/
What you can do is compile a small VB program with a For Next loop:
Private Sub Command1_Click()
Dim i As Long
Text1.Text = ""
For i = 1 to 5
Text1.Text = Text1.Text & QQ("Number: " & CStr(i)) & vbCrLf
Next i
End Sub
Private Function QQ(s As String, Optional sQ As String = """") As String
QQ = sQ & s & sQ
End Function
Run that through OllyDebug. There's a lot of junk you have to go through
before you actually find the Command1_Click routine, and you might
spend a day messing with it, but then you can change Command1_Click
to see what happens when you call a procedure.
Private Sub Command1_Click()
Dim i As Long
Text1.Text = ""
For i = 1 To 5
Call WriteIt(i)
Next i
End Sub
Private Sub WriteIt(i As Long)
With Text1
.Text = .Text & "Number " & QQ(CStr(i)) & vbCrLf
End With
End Sub
When I found the function by doing a search for strings (the function
name), OllyDebug seemed to think the function was data. OllyDebug
correctly inserted a With Text1 and End With but it seemed to be a
little out of place.
> I don't see why the different registers would need to be used for
> different uses if they're essentially CPU memory addresses, but
> I'm beginning to see the basic idea.
Think of them as registers, rather than memory addresses. They are
containers to hold information. Like a cash register is used to hold
different coins and dollar bills. They are a totally separate idea than
memory and it's important to make sure you when you talk about
memory you're NOT talking about registers and vice-versa. The
cash register is different than the safe but they hold the same things.
The cash register (CPU) is used constantly while the safe (memory)
is updated alot if there is alot of business going on or every so often
if there is only alittle business going on, generally speaking. :-)
> So the stack is essentially my own storage area that I pile pointers
> or literal values onto.....and that's *always* where the processing
> looks to find function parameters?
I believe that's how it works. Each program that runs gets it's own
stack that it uses. The OS operates with it's own stack. I'm hesitating
using the word *always* though.
> So if I were to call, say: DoIt 5, 3, 2 - where the 3
> parameters are all longs - I could conceivably look at the
> top 12 bytes of the stack while that's running (assuming one
> can look at the stack dynamically) and find the values
> 5, 3, 2 there?
There might be other things in there as well, depending upon the
application that compiled the program. I wouldn't depend upon
things being fixed in the stack until you've tested them out. The stack
can be used with With statements in VB to push the address of Text1
there so it can be readily used to reference Text1 (a textbox or combo-
box or whatever is used with the VB With statement).
> Is the heap, then, just that....a pile of memory addresses that
> represent my allocated variable space?
Someone else will have to answer exactly what a "heap" is in regards
to your question. I've always thought of the heap as the allocated
memory space but when I've looked up the definitions at wikipedia.org
I'm seeing a more complicated discussion of it. So I'll leave that question
for someone else to answer.
--
Jim Carlock
Please post replies to newsgroup.
|
|
|
|
|