Searched the board and am still confused. I don't want to use the fpu as I am unsure if all users will have a fpu, when did the fpu come around anyway? 3/4/586?

Anyway, I am converting one of my VB programs to Assembly and am stumped on a bit of code. Here is a link to the question I asked the VB groups a few years ago to come up with this code and will explain more of what I am trying to do:

Gunner's old Google article

And this is the code I am trying to convert:


For x = 0 To 7
If lngResult And 2 ^ x Then
chkProperties(x).Value = vbChecked
Else
chkProperties(x).Value = vbUnchecked
End If
Next


I can get a number between 1 and 255 and need to know what bit is set (correct term?) so if I get a number 48, then check box 5 and 6 are checked while the others aren't.

The number I get can be a combination of adding one or more of the following numbers:
1, 2, 4, 8, 16, 32, 64, 128.

x in the above code can be 0 to 7 and lngResult can be 1 to 255

Basically from the VB code, if lngResult AND 2 ^ x != 0 then set the check otherwise uncheck?
Posted on 2003-02-19 22:10:19 by Gunner
Here is one way...
X_to_Y_power MACRO _X_:REQ, _Y_:REQ

LOCAL _0, _1

mov ecx, _Y_
mov edx, _X_
mov eax, 1
_0: shr ecx, 1
jnc _1
imul eax, edx
_1: imul edx, edx
test ecx, ecx
jne _0
ENDM
:grin:

Posted on 2003-02-19 22:54:11 by bitRAKE
I didnt check this, or commented it, as i wipped it up in a hurry. But this should fit the bill.

The data segment is assumed to have a list of structure pointers to which the ".Value" structure entry is to be set or unset..

.data

chkProperties LABEL BYTE
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0

.code

DoChecks PROC uses EBX ESI lngResult:DWORD

mov esi, lngResult
xor esi, 0FFh

lea edx, chkProperties
xor ebx, ebx
mov ecx, ebx
inc ecx
.while( ebx < 8 )
mov eax, esi
and eax, ecx
.if( eax )
lea eax, [edx + 4*ebx]
mov [eax].SOMESTRUCTURE.Value, vbChecked
.else
lea eax, [edx + 4*ebx]
mov [eax].SOMESTRUCTURE.Value, vbUnchecked
.endif
shl ecx, 1
inc ebx
.endw
ret
DoChecks ENDP


Enjoy
:alright:
:NaN
Posted on 2003-02-19 22:56:53 by NaN
Isn't the FPU emulated, in software, on machines that don't have an FPU?
Posted on 2003-02-19 23:29:59 by scientica

Isn't the FPU emulated, in software, on machines that don't have an FPU?


They used to be emulated, IF THE PROGRAM HAD AN EMULATOR LIBRARY. The program had to be compiled with an emulator library so that the FPU could be emulated. Most HLL compilers had emulator libraries, but not assemblers, for the simple reason that the emulator library replaced all F* (ESC) commands with 'int xx' sequences, followed by a couple numbers as to which F* command it really was (for Borland compilers at least, I would suppose M$ would do something similar). If the emulator had detected a real FPU, the sequence was replaced with the actual instruction at run-time (this was in DOS days). If the program had no emulator library, not having an FPU would cause the program to fail.

Also some versions of MASM supported the use of an emu library, they automatically replaced all F* commands with the proper emu library sequences.

BTW the FPU has been around since the 8086. The first Intel FPU to be compatible with a x86 processor was the 8087, which could be connected to an 8086 or 8088, but as a separate chip with a separate slot. Further, you COULD connect an 8087 to an 80286, but if the 80286 entered protected mode, using the 8087 was not recommended because it assumed a real mode addressing. Starting with the 80287, handling of FPU addressing was turned over to the host processor, so that the FPU would follow any restrictions in memory addressing as is needed in protected mode.

Ja!
Posted on 2003-02-19 23:52:17 by AmkG
I meant to suggest this simple solution by my X_to_Y_power macro:
Your PROC a:DWORD, b:DWORD, etc:DWORD

LOCAL chkProperties[32]:CheckProperties

...
...

lea edx, chkProperties - SIZEOF CheckProperties
mov eax, lngResult
_0: add edx, SIZEOF CheckProperties
test eax, eax
je Done
shr eax, 1
jc Set
clear:
mov [edx].CheckProperties.Value, vbUnchecked
jmp _0
set:
mov [edx].CheckProperties.Value, vbChecked
jmp _0
Done:

...
...

ret
Your ENDP
Posted on 2003-02-20 00:32:18 by bitRAKE
Very cool! Thank you.

NaN, works like a charm but the checked and unchecked needed to be swapped. Thank you!

Macro King, I will keep em and try to learn what your code does, can't seem to follow it right now, coffee didn't kick in yet.

Thank you all!

Give you a preview of what I am doing in a few days... :)
Posted on 2003-02-20 09:39:43 by Gunner
Rob,

You are pretty safe in assuming FP support on anything that can reasonably run 32 bit windows. I have heard a long time ago of people who could run win95OEM on a 486sx but anything over that has FP support. 486DX, any pentium and I think the equivalent AMD processors from that period have FP so unless you are targetting stuff older than that which has big problems running even win95 OEM, you should not have to worry about it.

Regards,

hutch@movsd.com
Posted on 2003-02-20 17:46:38 by hutch--
BitRAKE's version is essentially the same. He is not using .if/.else/.endif and doing the compares as efficiently as possible. He decrements by one 'ChangeProperties' structure size initially, because the loop begins as "add ChangeProperties size". ( addr - x + x = addr ). Instead of rolling the data to the left as i had done, he is rollin the data to the right, and making use of the fact each bit will end up in the carry register when it rolls out. Is if a 1 is poped out, set the check, if a zero then clear it. Then loop back, add another size amount of byes to the next structure and do it again.

His version will handle 32 bits if need be. He didnt tell much on how to use it, but you need to have the data your testing for bits in EAX, and format it (as i have) with "xor EAX, 0FFh" if you dont want to process anymore than the first 8 bits (and subsequently the first 8 structures). If you have junk data in say AH and no provision for more than 8 structrures, you will end up with problems ;)

:alright:
NaN
Posted on 2003-02-21 04:08:18 by NaN
If the value you are setting is a byte, and its either 0, or 1 then you can do this:


mov ecx, 8

@@:
dec ecx
bt eax, ecx ; You may choose to use btr, btc, or bts instead here
setc SomeByteAddressHere ; Or maybe setnc
jnz @B


Mirno
Posted on 2003-02-21 06:29:36 by Mirno
I think it would be a good idea to use the FPU, because even my previous computer (Cyrix 6x86 PR166+) had a FPU (despite being a weak one that would struggle under the pressure of Quake >=| ) . Everyone should have one, I wouldnt consider running any Win32 OS on a CPU less than a 486DX.
Posted on 2003-02-21 07:35:42 by x86asm
As far as technology goes, I am still in the "caveman" days. :( Still use 133mhz pentium and the code posted here is just fine.

I guess I could do a check on the value and if it is above 255 just do nothing..

Here is what I did:

Created a structure for the checkbox handles


strCheckBox struct
cb1 DWORD ?
cb2 DWORD ?
cb3 DWORD ?
cb4 DWORD ?
cb5 DWORD ?
cb6 DWORD ?
cb7 DWORD ?
cb8 DWORD ?
strCheckBox ends


I create the checkbox and save the handles: mov CheckBox.cb1, eax

Then I grab the value I need and use the code from NaN:


DoChecks proc uses ebx esi edi lngResult:DWORD

mov esi, lngResult
xor esi, 0FFh
lea edi, CheckBox

lea edx, chkProperties
xor ebx, ebx
mov ecx, ebx
inc ecx
.while (ebx < 8)
mov eax, esi
and eax, ecx
.if (eax)
push ecx
push 0
push BST_UNCHECKED
push BM_SETCHECK
push [edi + 4 * ebx]
call SendMessage
pop ecx
.else
push ecx
push 0
push BST_CHECKED
push BM_SETCHECK
push [edi + 4 * ebx]
call SendMessage
pop ecx
.endif
shl ecx, 1
inc ebx
.endw
ret
DoChecks endp

and all works beautifully!

This preview will only show the zones: name/icon/description, flags (what the code above is for), Current/Recommended/Minimum security.

Added New/delete zone yesterday and want to add few more before I release another test version.

Need more info on IE Zone Editor? Visit my page for more info and/or grab the VB version for comparison

What am I working on? The new IE Zone Editor. Haven't updated it in almost a year. Here is a preview:
let me know what you think...
Posted on 2003-02-21 08:24:57 by Gunner
Back to the original post.
I don't want to use the fpu as I am unsure if all users will have a fpu, when did the fpu come around anyway? 3/4/586?

Sorry to seem so harsh but thinking of using the FPU strictly to get a power of 2 is ludicrous. Simply put 1 in a register and shift it left by the required power. That would be some 100 times faster than using the FPU.

(Analyzing a problem in detail can often result in simple solutions. Some of the other suggestions for solving your routine also seem excellent.)

Raymond
Posted on 2003-02-21 09:30:25 by Raymond

Back to the original post.

Sorry to seem so harsh but thinking of using the FPU strictly to get a power of 2 is ludicrous. Simply put 1 in a register and shift it left by the required power. That would be some 100 times faster than using the FPU.

(Analyzing a problem in detail can often result in simple solutions. Some of the other suggestions for solving your routine also seem excellent.)

Raymond


Your right, but we assume that the person wants to raise a number by an arbitrary exponent.
Posted on 2003-02-21 19:21:53 by x86asm
x86asm
Your right, but we assume that the person wants to raise a number by an arbitrary exponent.

Sorry again. If you look at how this thread was started, the problem centered around porting some VB code to asm. AND the only exponential was a 2^x, x being an integer.

Raymond
Posted on 2003-02-21 19:58:35 by Raymond
Raymond Said:
...
Sorry again. If you look at how this thread was started, the problem centered around porting some VB code to asm. AND the only exponential was a 2^x, x being an integer.


Ah, but if you followed the link in the top post to my NG question from a few years ago, you would of seen x is a number from 0 to 8 or something like that.
Posted on 2003-02-21 20:20:46 by Gunner

Raymond Said:
...

Ah, but if you followed the link in the top post to my NG question from a few years ago, you would of seen x is a number from 0 to 8 or something like that.


Is X an integer? It is, isn't it?

Then shifts WILL work. 2^n is always implementable by shifting if n is an integer. As a matter of fact, an asm programmer can do something like:



mov ecx,0
mov eax,IngResult
mov edx,0

loopback:
shr eax,1
mov chkProperties[edx].Value,vbUnchecked
jnc bitnotset
bitset:
mov chkProperties[edx].Value,vbChecked
bitnotset:

inc ecx
add edx,sizeof ?? ;;!!!!!<---size of whatever structure chkProperties is.
cmp ecx,8
jb loopback


This is simply exploiting the SHR instruction, which puts the bit shifted out in the 'C' or carry flag. A cleared 'C' flag triggers the 'JNC;' this means that the corresponding bit is a ZERO or cleared.
Posted on 2003-02-22 06:44:59 by AmkG