This thread is dedicated to developing a DLL for use in Visual Basic using MASM assembler methods to build the DLL.

I am new to ASM and am just discovering the needed work-arounds for 8-bit to 16- and 32-bit conversions.

I'm using "Assembly Develop Studio 1.0" from configured for MASM32 and library support that I found at

I have also installed IdeasM 1.0 for use with UEDIT, it is very useful and provided essential information for getting ADS 1.0 configured to work with MASM32 instead of TurboASM. Making direct use of the extensive support for MASM seemed like the way to go.

Next post is the code I am compiling that will hopefully emulate AVR functions to VB.

There is a possible advantage to using a segmented non-flat memory model. I think its possible to work with 8-bit values and addresses can be 16-bits. Then of course we are not working with WIN32.

So its necessary to consider what the experts think about this part of the projects. A person who knows both platforms well would possibly have a preference. It depends allot on how much work is involved in converting 8-bit values and pointers.

Contributions gladly accepted.

-AV- :grin:
Posted on 2002-03-11 14:16:59 by avrster
It compiles, with just a single error as I'm working out a conversion of 32 or 16 bit values in indexing. I'm not sure what the wanted value is.

The main method is prototyped that tests the reason for calling the DLL. Also it willl be possible to export methods to Visual Basic using the needed _stdcall convention.

I began with a simple skeleton and made sure I could include files and libraries. Then I made tables for the SBOX etc. and added a few simple functions that will move data, or bitflop it.

The main intent is to enhance my capabillities with VB as related to AVR emulation and other applications.

Looking at a DLL with IDA, it was obvious there is tremendous overhead added by the development system. This obfuscates the code, which is possibly a good thing for some functions. However it cannot be made standard practice in development of AVR emulation methods. Win32 Assembler development is relatively new, but it is increasingly getting easier to learn and pull-off.

Anyone serious about VB development should take a look at enriching their VB with MASM32 development for WIN32 DLL functions.

The going is a little slow, but I expect it to get a little easier once I learn a few more fundamentals about ASM.

With DEF file to define the EXPORTED methods I hope to begin testing some form of the DLL in VB soon.

I need to get into the habit of using function prototypes. Also I think I'm almost ready to implement the DLL in a testing mode to get the VB side of things going, and to make sure the bases are covered. I want to explore the limitations on variable passing to see if its possible to pass strings and return them, or pointers to them.

I'll appreciate input on whether to attempt emulation of AVR processing on a 32-bit platform, or if it will be an easier project to do it on a 16-bit platform.

3-10 10PM
I made some changes switching to model that defines segments allowed some of my instructions to work. This is new ground for me I'm going way out to get this up on my VB development. Some of the methods are looking OK.

EDITED 3-12 4:45AM CST Revised Attachment


Reformatted: 3-12 8:15 CST

Posted on 2002-03-11 14:20:10 by avrster
Anyone serious about VB development should take a look at enriching their VB with MASM32 development for WIN32 DLL functions.

Thats an excellent idea, you wouldn't get any argument from me.

However, just what are you trying to accomplish? It's hard ot get that from your code.
Posted on 2002-03-11 22:34:17 by Ernie

I actually cannot see the problem of writing DLLs for VB in MASM, the main problems will be knowing what is passed to the DLL and what is passed back to VB.

MASM can handle both STDCALL and C calling conventions and with this you can handle the VB BYVAL or BYREF parameter passing with no problems, as long as you know which is which with your DLL.

Addresses OR values are no problem to MASM at all.

Posted on 2002-03-12 00:51:14 by hutch--
The problem I see with this particular processing is that ADDS affect the carry bit and the carry bit status is used to determine output. Everything starts with 8-bit values, but since the registers a 16-bit there will be no carry flag.

Is there a mode that allows the carry to be set on 8-bit results rather than 16-bit?

A work-around is-going to take up time.

I Reformatted the code above.

It occurred to me that

adc al,al

will affect the carry bit.

Also putting an an 8-bit value into the high byte before doing

adc ax,ax will also affect the carry bit if the result requires 17 bits.

I much prefer trying to emulate or implement something that writing it from scratch. So far, so good. I'll be looking at passing parameters aafter implementing the basic methods. Just a few more to go! They are smaller.


Posted on 2002-03-12 08:13:44 by avrster

The bits of code that you have posted so far look like 16 bit code so I am not sure if you are writing 16 or 32 bit code for your MASM dll for VB.

The problem is you have not posted enough info for anyone to help you. Are you using 16 or 32 bit VB. Are you trying to use 16 or 32 but assembler.

What form is the data you want to pass, how do you want to return it to VB etc ....

If you can tell us more, someone may be able to help you.

Posted on 2002-03-12 09:13:18 by hutch--

Great compiler. You guys DU are up un your computing. Defending yourselves pretty well against the Viri too. I've been checking the chart at Trend Micro for Pc_Housecall stats.

Presntly I'm in a phase of just doing whatever it takes to get the AVR Montgomery functions to compile. It worked out better to use the 16-bit mode for indexing and because I'm really working with lots of 8-bit values I works out well. I'm grasping a few of the potential problems before they occur in debugging. This carry flag problem was easy to solve. One function works better if you put the data into the high byte of AX, another works out if you drop them into the low byte and use ADC, AL,AL to set the carry bit.

All I need at this point is to hear it from the experts that I can pass strings to & from VB. I was thinking about it and realize with at the exposed methods in the VB6runtime.dll or whatever its called, there has to be a way to put values into a buffer and let VB know it is ready. After getting a few more methods into the DLL, I can focus in to the parameter passing.

This is great stuff. I like the tools.

That Assembly Developer Studio is simple and easy to pickup. I configured it for your latest MASM32 compiler. Seems like when everything is formatted nicely it parses faster.

I think I can learn to leverage VB with MASM. You have something going there Hutch... its big.

Posted on 2002-03-12 09:40:10 by avrster

All I need at this point is to hear it from the experts that I can pass strings to & from VB. I was thinking about it and realize with at the exposed methods in the VB6runtime.dll or whatever its called, there has to be a way to put values into a buffer and let VB know it is ready. After getting a few more methods into the DLL, I can focus in to the parameter passing.

Hi avrster,
well imo the best way to interface with VB even with asm is to use COM technology
Anyway if u wanna use the dll way u should deal with BSTR
the strings under VB
U should use WideCharToMultiByte() to deal with them
The exports of VB runtime r quite clear as names on what they do but if u need some help with some specific api u can ask

See ya
Posted on 2002-03-12 10:00:45 by NikDH
Hmmm, i almost burst out laughing when i saw your previous post. You are heading down the wrong track fast, it would be interesting to see where you end up :)

Yes, you can pass strings to and from VB, but let me get something else straight first: if you are programming in 32 bit VB, then your dll will have to be written in 32 bit asm. 32 bit VB cannot call a 16 bit dll without going through a "thunking" process. You should not need to call a 16 bit dll. If the asm code you are working with is 16 bit, then port it to 32 bit. There are plenty of people in this forum well qualified to assist you.

Back to the strings:
you DO NOT and SHOULD NOT use the VB runtimes directly for string handling. The functionality that is exposed is undocumented and unsupported by MS, and can change at any time at MS's discretion, usually by a service pack being applied. It is also an extremely torturous way of doing what you want to do.

There are two straight-foward ways to pass a string from VB: ByRef or ByVal. Under normal circumstances, i would advise not to use ByRef. Your asm functions should use the stdcall calling mechanism, and normally you should pass your strings from VB ByVal.

If you pass the strings ByRef, your asm function will receive a pointer to a BSTR. If you pass ByVal, VB copies the string to a temporary place on the heap. When it makes that copy, it changes the format of the string from UniCode to ANSI, so your asm function will receive a pointer to an ANSI string stored in temporary space. That copy of the string is destroyed when you return to the VB function, so if you need a copy of it then your asm function will have to copy it to a private buffer.

The third way to pass a string to an asm function is to first copy the string to a byte buffer using CopyMemory(), then pass the first element of the byte array, which means that your asm function will receive a pointer to the first element in the array (just like in C). You can then operate on this byte buffer, then when you return to VB you use CopyMemory to copy the byte buffer back into the original string. This method is not needed often, should only be used for fixed-length strings, and should only be used if you know what you are doing (it leads to GPFs if you get it wrong).

Posted on 2002-03-12 16:42:51 by sluggy
Yes sir,, I thank you for the facts.

The attachment here is a 16-bit collection of methods converted from AVR 8-bit code.

I had trouble figuring out how to index in 32-bit mode because my data sizes were not matching. If someone wnats to take a look at what it will take to convert these methods to 32-bit I will be more than interested in their suggestions. So far I have not got 32-bit indexing and data types figured out. The conversion to 16-bit might just be a stepping stone.

I have read a little about THUNKING and would prefer to steer clear.

I need to read you post more closely.


Posted on 2002-03-12 17:16:35 by avrster

You can do byte level processing in 32 bit with no problems at all, it just means that you have to learn the coding techniques, indexing is not a problem, increment the index by 1 to handle BYTE data, 2 for WORD data, 4 for DWORD data.

When you settle on the parameter passing method from VB to the DLL and how you want the data to return to VB, the rest is simple. You can simply afford to ditch 16 bit assembler, you can do all of this stuff in 32 bit better.

There is still no descripton of "AVR" emulation and stuff like the "ADDS" effect so there is little to work on at the moment.

See if you can make a little more info available as its not making much sense at the moment.

Posted on 2002-03-12 17:38:29 by hutch--
avrster, 32-bit addressing is the same as 16-bit, but with
32-bit registers. The code would greatly benefit from it's use.
mov al, [EBX + 13]

mov al, [EBX + ECX * 8 + 13]
I will convert a PROC or two when I get home to help you. I like your coding style of using EQUates to make the code more readable - I do the same thing. :)
Posted on 2002-03-12 17:45:04 by bitRAKE
I just knocked myself out for a couple days to dive into this after researching it. Creating the DLL is the thing to do to spawn further development. It gets very interesting.

I got a taste of converting AVR code to 16-bit. I could grasp the code needed to do it without any MASM experience. Honestly I think it takes a little programmers intuition about 32-bit coding to do a really good job of it. Migrating from an 8-bit world to a 32-bit is a big step. You don't just absorb it. It comes with honest work. I have respect for that.

On your side its got to be a little interesting to see someone come along and attempt to put it together.

The AVR is a register-intensive RISC processor. The x86 has a very powerful and flexible instruction set. You start coding and for each mnemonic there has GOT to be a mode that applies to your particular instance. The x86 is like a TANK and the AVR is like a sports car. What's interesting is seeing the simple over and over techniques the TANK can use to implement the straight-forward AVR.

Yep,, once I get a handle on how the 32-bit mode adapts to the processing in this Montgomery DLL I'll be openning a new chapter in my programming conquests. Life is grand!

There is allot of potential in combining VB and MASM32. I have a full-blown VB E-mail application that can benefit as well, but for now the Montgomery processing is to get another project off to the races.

Thi parameter passing thing is something that needs to be done properly the very first time. Then it won't be necessary to relearn the correct method. Allot of people probably wish they had THUNK just a little harder before they implemented. (Of course with Microsoft out there mucking up everything just when its seems that everyone is getting a little too robust for their ambitions...)

Posted on 2002-03-12 21:14:21 by avrster
Migrating from an 8-bit world to a 32-bit is a big step
No its not. It is easier for new people to do 32 bit stuff, because they do not have to deal with the complexities of segmented addressing.

What's interesting is seeing the simple over and over techniques the TANK can use to implement the straight-forward AVR.
I am not familiar with the algorithm that you are porting, but this is what i would suggest: first, just get it going using the normal opcodes. Then read some tutorials on MMX and SSE instructions, evaluate how they may help with the optimisation of the algo, then introduce them into the code if appropriate.
Posted on 2002-03-13 04:27:13 by sluggy
This processing affects the carry bit when the lower order bits are added. I think it will correctly emulate the processing done on the AVR. I added the adc al,al instruction and dropped the result back into the location for each manipulation.

mov ax,
adc al,al
mov ,ax

mov ax,
adc al,al
mov ,ax
mov ax,
adc al,al
mov ,ax

mov ax,
adc al,al
mov ,ax
mov ax,
adc al,al
mov ,ax
mov ax,
adc al,al


Fixed it in this file. V (Below) Also added main encrypt and decrypt methods.

Yep, the experts have concurred that conversion to 32-bit processing makes for an all-around easier time of it in VB. This is essentially the advice I was hoping for. So,, its now become a matter of marvelling at the code and figuring out how to whip it into a 32-bit emulation. Just the simple methods are called for. Advanced optimizations if possible are really an advanced topic that is reserved for the experts who might be pondering some of it right now actually.

To the most recent edited attachment I have made headliner notations about parameters to be passed.

Posted on 2002-03-13 07:45:40 by avrster
Could you state the algo mathematically? The above posted code could be realized with just shifts or rolls, but I am not certain of what the larger goal is. Does the attached code work for your application as it is?
Posted on 2002-03-13 10:00:36 by bitRAKE
The attached file is actual AVR code that I took from source that compiled on the AVR for the Montgomery DES processing.

I broke that AVR application source into components hoping to simplify the analysis. When complete high-level functions assembled, then I had the pieces together in a module.

Advancing development of a simulation in VB requires this processing. Analysis will reveal that there is more processing that has not been implemented in the module as no use of the EXPONENTS and MODULUS has been shown. That processing is at this point external, but I am looking to see what is involved and what would need to be added.

Its just a few methods that index the tables and chain processing that uses the ENCRYPT-DECRYPT methods. The DLL can probably be done keep all other methods internal, exporting only the ENCRYPT and DECRYPT methods. This will be dtermined soon.

I have no description of the ALGO. Its industry-standard processing called "Montgomery" that does exponential multiplication to define keys from stream data.

Posted on 2002-03-13 10:16:55 by avrster
This code is accomplishes the same thing as what you posted:
;mov ax,[REGS +_R24] 

;adc al,al
;mov [REGS +_R24],ax

rcl BYTE PTR [ 1 + REGS +_R24], 1

;mov ax,[REGS +_R24]
;adc al,al
;mov [REGS +_R24],ax

rcl BYTE PTR [ 1 + REGS +_R24], 1

;mov ax,[REGS +_R23]
;adc al,al
;mov [REGS +_R23],ax

rcl BYTE PTR [ 1 + REGS +_R23], 1

;mov ax,[REGS +_R24]
;adc al,al
;mov [REGS +_R24],ax

rcl BYTE PTR [ 1 + REGS +_R24], 1

;mov ax,[REGS +_R23]
;adc al,al
;mov [REGS +_R23],ax

rcl BYTE PTR [ 1 + REGS +_R23], 1

;mov ax,[REGS +_R22]
;adc al,al
;mov[REGS +_R22],ax

rcl BYTE PTR [ 1 + REGS +_R22], 1
I do not believe that this is anywhere near optimal though. As Sluggy suggests, a couple orders of magnitude could be achieved with MMX, without much effort.
Posted on 2002-03-13 10:34:30 by bitRAKE
Code Segment Use32 Dword Public 'CODE'

Assume Cs:Code

DECODE integer 247,226,60,191,4,91,170,236,155,135,6,89,173,244,224,10
integer 98,08,149,99,95,54,74,101,56,209,115,174,145,173,142,240


I need to learn to make proper assertions for table locations so as to be able to access them from base locations starting at zero for simpler indexing.

Manipulation of the compiler commands to define the segment (within the data segment preferably) is required.

Using the most desireable option to define my table data structure "Use32 Dword" is also required.

This is a simple thing to fixup before diving into the 32-bit coding.

Posted on 2002-03-13 10:36:32 by avrster
Setting the segment registers to access the data with a zero offset is not possible in windows. Windows manages the segment registers, and gives each application a 32-bit address space (not all is accessible). Are you programming for windows?

; under windows
assume CS:FLAT

;under your own operating system... :)


assume CS:CODE
Posted on 2002-03-13 10:57:09 by bitRAKE