News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

BTR usage.

Started by KeepingRealBusy, December 12, 2008, 12:49:57 AM

Previous topic - Next topic

KeepingRealBusy

I pasted this code into the C2Test2 program and executed it:


.data
BitStr1 DWORD -1
BitStr2 DWORD -1
BitStr3 DWORD -1
BitStr4 DWORD -1
BitStr5 DWORD -1
BitStr6 DWORD -1
BitStr7 DWORD -1
.code
xor ebx,ebx
btr BitStr1,ebx
inc ebx
btr BitStr2,ebx
mov ebx,32
btr BitStr3,ebx
inc ebx
btr BitStr4,ebx
mov esi,OFFSET BitStr6
btr DWORD PTR esi,ebx
mov eax,BitStr1
print hex$(eax)," "
mov eax,BitStr2
print hex$(eax)," "
mov eax,BitStr3
print hex$(eax)," "
mov eax,BitStr4
print hex$(eax)," "
mov eax,BitStr5
print hex$(eax)," "
mov eax,BitStr6
print hex$(eax)," "
mov eax,BitStr7
print hex$(eax),13,10,13,10


The following was the resulting output line:


FFFFFFFE FFFFFFFD FFFFFFFF FFFFFFFE FFFFFFFD FFFFFFFF FFFFFFFF


This example shows that the BTx instructions work from bit 0 of the first byte
of the specified memory in a BIG-endian BIT mode, but in a LITTLE-endian BYTE
mode, something that the AMD spec does not specify, so I tested it to find out.

You will note that for test 3 and 4, the byte following the specified memory
location is the byte that was modified - as I expected, and everything is good.

Now for the problem. The test for BitStr6 was to try to specify a bit string
whose beginning address was in a register. This did not work. Evidently, the
assembler still treats this as a register operand of 32 bits and not a bit
string pointer so it changes nothing. Is there any to do this? I have a huge
(512MB) array  I allocated via VirtualAlloc that I was going to attempt to
manipulate with BTR. Must I allocate this buffer as a huge buffer and just pass
the starting address as tests 1 thru 4?

Does anyone know, offhand, what that thread was that talked about allocating
huge buffers and encountering slow assemblies - and gave a way to use ORG to
get around the problem? I have searched for huge buffers, big buffers, slow
assembly, and ORG, but cannot find exactly what I remember seeing without
looking through 69 pages of hits.

Dave.

sinsi

Quote from: KeepingRealBusy on December 12, 2008, 12:49:57 AM
Does anyone know, offhand, what that thread was that talked about allocating
huge buffers and encountering slow assemblies - and gave a way to use ORG to
get around the problem? I have searched for huge buffers, big buffers, slow
assembly, and ORG, but cannot find exactly what I remember seeing without
looking through 69 pages of hits.

Dave.

This the one? Assembler hangs for big buffers in .data? section
Light travels faster than sound, that's why some people seem bright until you hear them.

KeepingRealBusy

sinsi,

Yes! Thank you.

Now for my first questions, do you know how to do what I want using BTR?

Dave.

sinsi

From Intel:
QuoteIf BitBase is a memory address, the BitOffset can range has different ranges depending on the operand size.
The addressed bit is numbered (Offset MOD 8) within the byte at address
(BitBase + (BitOffset DIV 8)) where DIV is signed division with rounding towards
negative infinity and MOD returns a positive number.

Looks like you can load up a register with any number from -231 to 231 and test that bit

  mov eax,128
  btr bitmap,eax

will test the "128th" bit of memory.

  mov eax,128
  mov esi,offset bitmap
  btr dword ptr [esi],eax

does the same.

Is this what you wanted?
Light travels faster than sound, that's why some people seem bright until you hear them.

KeepingRealBusy

sini,

Bingo! You get the gold ring! The answer is "DWORD PTR [esi]", not" DWORD PTR esi", I missed the brackets. Works now. Thank you.

Dave.

Rockoon

It isn't "big endian bit mode"

Most endian confusion results from people not adapting to text representations.. and this is one of them.

If you change your program so that instead of outputting the data as hex dwords you output it as hex bytes.. your output would begin..

"FE FF FF FF..."

Note that in "FFFFFFFE", that "E" is the LEAST SIGNIFICANT nibble.
Note that in "FE", that E is again the least significant nibble!

We represent and read numbers from most significant to least, which is the cause of confusion here!

The x86 is very consistent here. The least significant bit is lowest in memory, the least significant byte is lowest in memory, the least significant word is lowest in memory..
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

KeepingRealBusy

Rockoon,

I guess I was referring to the declaration of the data more than anything else. If you specify a DWORD array, the least significant DWORD is specified first, then the more significant DWORDs, and finally the most significant DWORD i.e. from left to right, however, the bits in the bytes are defined from the right to the left. By the way, byte numbering in words is not always consistent within a machine, I have worked on systems where the I/O system was numbered from most the significant byte of 0 to the least significant byte of 3 within a word, whereas the CPU had exactly the opposite numbering. Led to many errors during development.

My test program was just a simple test to see what would happen. I agree that output as hex bytes would show the result more correctly, especially if the bytes were output in the inverse order with the most significant byte first, you could see the bites marching up the byte string from the right side to the left.

Dave.