Hello all.  I am trying to program an implementation of the solitaire cipher in asm.  It has to do with a deck of playing cards so I need to make an array of 54 integers.  I will need to be able to find certain cards in the array and perform operations on them like moving cards around and such.  I have not used arrays before so I am quite stuck. I know exactly what I need the program to do procedure-wise but I get stuck because I don't know how to implement things. 

Can someone nudge me in the right direction? :)
Posted on 2006-07-24 09:54:30 by Desp
You understand what an integer is, and you understand what an array is.
What's the problem?

Moving 'cards' around is a matter of moving the array elements around within the arrayspace.
Since you're only working with integers, it's VERY simple indeed.
What you need to understand is just how to calculate the ADDRESS of a given array element.
That's simply the zero-based element number multiplied by the element size, plus the Base Address of the Array.
Since your array elements are integers (I assume you mean dword integers), it's quite simple.

Here's example code:

.data
MyArray dd (place 54 values here)

.code
;Example : obtain the 15th value from the array
mov eax,MyArray[15*sizeof dword]


How hard was that?

Posted on 2006-07-24 11:41:38 by Homer
Hi Desp,

As Homer said, arrays are quite simple, here's a step by step...

First allocate enough memory for the entire array, in your case 54 DWORD values should be enough...

MyArray DD 54 DUP (?)

In this case I left the values uninitialized so they will all be NULL

To move things into the array or out of it, we use a base register and an offset. The base register (we'll use EBX in the example) contains the base address of the array, the offset contains the particular item we want...

mov ebx, offset MyArray
mov ecx, 4 ; the forth element of the array

So you would use the following syntax to get your items...

mov reg32,

or in other words...

mov eax, ; read a value
mov , eax ; write a value

4 being the scale (or size) of a dword to make sure we skip 4 bytes each time.

Hope this helps you out a bit

Donkey
Posted on 2006-07-24 11:54:02 by donkey
Thanks so much for the help guys.  I have gotten a bit farther.  I can easily swap two cards but as for some of the more complex movements I am stuck.  I need to rotate the array somehow.  In another step I need to move a card down two elements.  There is also a "triple cut" procedure that looks like it is going to be hard.  Should I just initialize a new array and fill in values 1 by 1?  There are some code examples (not asm) on Schneier's site: http://www.schneier.com/solitaire.html but I can't reverse engineer them.  There must be an easy way of doing this that won't produce too much code.

Update: I have had some success.  I am now stuck at step 3 and 4 the "triple cut" and "count cut".  If I can get these two done the rest is easy.  Please enlighten me :)
Posted on 2006-07-24 23:07:41 by Desp
Well, I have figured out a lot more than I though I would.  I have programmed the cipher correctly.  My only problem now is that I want to create an output .txt file and write output there.  I've looked around but haven't found anything useful.  I use createfile to make the .txt file but how do I write to it?  Ideally I would like to be able to write to the file one character at a time.  Would I have to move the pointer position to do this? 

I am so close.  :D
Posted on 2006-07-27 09:05:10 by Desp
WriteFile
Posted on 2006-07-27 09:42:34 by arafel
To dump the array (I assume it's 54*4 bytes long), you'd use such code:

.data

MyCards dd 54 dup (?)


OutputFileName db "CardsDumpFile.txt",0
.code


DumpCardsToFile proc lpszFileName
local FileHandle1
local NumBytesWritten ; useless for us, but required

;---------[ create the file for writing ]-----------------------[
invoke CreateFile,lpszFileName, GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
mov FileHandle1,eax
.if eax == -1 ; INVALID_HANDLE
ret
.endif
;---------------------------------------------------------------/


; write the array of 54 DWORDs into the file
invoke WriteFile,FileHandle1,addr MyCards,54*4,addr NumBytesWritten,0


; close the file
invoke CloseHandle,FileHandle1


ret
DumpCardsToFile endp





main proc
invoke DumpCardsToFile,addr OutputFileName

ret
main endp



I was also a bit frustrated with my first experience of writing to files from ASM.
It's nice seeing people progress with just a bit of help from the others ;)
Posted on 2006-07-29 13:29:10 by Ultrano
If you want to output to a (readable :P) text file, you'll need to do integer->ascii conversion. Probably the easiest (and pretty inefficient, but irrelevant here) would be using wsprintf from user32.dll...
Posted on 2006-07-30 11:34:55 by f0dder