First, thanks to those who helped with my last post, it now works. Anyway, I'm trying to set up a structure that would look something like this in C++:

struct People {
char names;
char phonenumbers;
}

I'm having trouble getting and putting strings into the structure though, and I'm not sure my professor should us how to do it right (set up the struct). Any help on this would be great.
Below is the code I'm working on. First the user is prompted for a command (which works), and then the command executes. Below shows only up to the Create Entry command.

.DATA
TheCommand DB 'Command: ', 0
NumEntries DD 0
ThePtr DD ?
CEError DB 'Error: Cannot create entry', 10, 0
EnterName DB 'Enter Name: ', 0
HoldName DB MAX_NAME_LENGTH + 1 DUP (?)
MAX_ENTRIES EQU 10
MAX_NAME_LENGTH EQU 10
MAX_PNUM_LENGTH EQU 10

.CODE
PUBLIC proj2_main
proj2_main:
push ebx
mov ebx, ThePtr
projectloop:
; read character chosen
mov ecx, OFFSET TheCommand
call print_string
call read_char

cmp al, 'c'
jne NotCE
; Create Entry
cmp NumEntries, MAX_ENTRIES
jge CEErrorMsg

mov ecx, OFFSET EnterName
call print_string
mov ecx, OFFSET HoldName
mov edx, MAX_NAME_LENGTH
call read_string

; My thinking here was that now that the string was in ecx, I'd
; load it character by character into the struct in ebx
; here I'm just testing with the first character
mov al, BYTE PTR

; The line below will give me the error of trying to referance memory at
; 0x0000000 and that the memory could not be "written"
mov BYTE PTR , al

; Below is to test to see if the character transfer worked. If I block out
; the line "mov ebx, ThePtr" at the top and change "al" to "'a'" in the above
; line, the correct character will print. If I Just take out the "mov ebx, ThePtr"
; line, a blank space will print.
mov cl, BYTE PTR
call print_char

jmp projectloop


Here's what the read_string function looks like just in case it helps:

void _fastcall read_string(char *str, unsigned long max_chars) {

if (max_chars == 0)
return;

char c;

while (isspace(c = cin.get()))
; // empty loop body

do {
*str++ = c;
max_chars--;
}

while (max_chars && !isspace(c = cin.get()));

while (!isspace(c))
c = cin.get();

cin.putback(c);
*str++ = '\0';
}

Note: I'm using VC++ 6.0 and am working with a Win32 Colesole Application.

later
Posted on 2002-03-26 11:52:47 by PAT or JK
.DATA

NumEntries DD 0
ThePtr DD ?

TheCommand DB 'Command: ', 0
CEError DB 'Error: Cannot create entry', 10, 0
EnterName DB 'Enter Name: ', 0
HoldName DB MAX_NAME_LENGTH + 1 DUP (?)

MAX_ENTRIES EQU 10
MAX_NAME_LENGTH EQU 10
MAX_PNUM_LENGTH EQU 10

People STRUCT
name db (1+MAX_NAME_LENGTH) dup (?)
phone db (1+MAX_PNUM_LENGTH) dup (?)
ENDS
Now you need to allocate some memory for the data structures and store the pointer to that memory in ThePtr.
Posted on 2002-03-26 12:55:16 by bitRAKE
Can you give a quick example, I'm not sure how to do that part.

later
Posted on 2002-03-26 14:02:17 by PAT or JK
For accessing the struct, i would do it something like this:



LOCAL blah : People

lea esi, blah
assume esi : ptr People
invoke lstrcopy, [esi].name, <ptr to your string>
Posted on 2002-03-26 16:36:37 by sluggy
My professor just sent this out to the class today: (he added something to the project)

"Also, I'd like to reiterate what I've been saying all semester about not using any high-level facilities of the assembler. One particular thing which you might be tempted to use in this project is your assembler's ability to declare data structures, giving them field names like you do in C. I don't want to see this in anyone's projects. You may use EQU statements if you wish to give symbolic names to your data offsets, but using the former feature doesn't help you learn anything about data structures and how they are represented. Remember, a good general rule to use is that if it shields you from some ugly details, I probably don't want you to use it. "

Is there a more basic way to do it, sort of like how I was doing it? In the notes for example, he gives this example:

struct A {
int a; // 0
char b; // 4
short c; // 6
}

Ptr->b = 'a'
=
Ptr DD ?
mov eax, Ptr
mov BYTE PTR , 'a'

That sort of seems like what I'm doing, but it doesn't appear to work for me. Thanks for all the replies so far.

- Patrick

later
Posted on 2002-03-27 13:00:38 by PAT or JK
Try this code:


.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE

INCLUDE \masm32\include\kernel32.inc
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDE \masm32\include\user32.inc
INCLUDELIB \masm32\lib\user32.lib
INCLUDE \masm32\include\masm32.inc
INCLUDELIB \masm32\lib\masm32.lib

;A STRUCT
; A DW ?
; B DB 2 DUP(?)
; C DW ?
;A ENDS

.DATA

A DB 6 DUP(0)
Bfr DB 9 DUP(0)

.CODE

Start:

lea esi, A
mov WORD PTR [esi], 9
mov BYTE PTR [esi+2], 'A'
mov BYTE PTR [esi+3], 0
mov WORD PTR [esi+4], 5

push esi

xor eax, eax
mov ax, WORD PTR [esi]
invoke dwtoa, eax, OFFSET Bfr
invoke MessageBox, 0, OFFSET Bfr, 0, 0

pop esi
push esi
add esi, 2
invoke MessageBox, 0, esi, 0, 0

pop esi
add esi, 2
xor eax, eax
mov ax, WORD PTR [esi+2]
invoke dwtoa, eax, OFFSET Bfr
invoke MessageBox, 0, OFFSET Bfr, 0, 0

invoke ExitProcess, 0

END Start
Since you said your professor doesn't like the HLL style in assembler, A DB 6 DUP(?) is the same as the structure declared above. ;)
Posted on 2002-03-27 14:20:21 by stryker
What i would do is this: code in the high level stuff, then compile it, then dis-assemble the code to check what the compiler did to it.

Also, if you use VC to do your asm coding, you are in luck. When in debug mode and stepping through the code, the debugger offers you two views of the code: your actual code, and the instructions that your code is compiled to. So, in the second view, .IF and .ENDIF are broken down into their correct jumps, .phone would be broken down to byte ptr , etc.
Posted on 2002-03-27 16:50:15 by sluggy