The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: iaNac on October 04, 2006, 02:21:27 AM

Title: Please help... newbie problems loading struct array with mixed data types
Post by: iaNac on October 04, 2006, 02:21:27 AM
I'm transitioning from vb (recently) and pascal (decades ago) with very little asm background (tasm on a TRS80) and I'm hung up on some rookie stuff.  I've defined a structure as follows:

CRI struct
    DrugForm BYTE 32 dup (" ") ; example: "Metoclopramide 5.0 mg/ml"
    DrugDose REAL4 ? ; example: 1.25
    DrugUnits BYTE 12 dup (" ") ; example: "mg/kg/day"
    FluidRate REAL4 ? ; example (ml/hr): 8.3
    FluidVol DWORD ? ; example (ml): 1000
CRI ends

and an array in WinMain as follows:

WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
:
LOCAL cri[11]:CRI ; create array to hold 12 drugs
:

What I'd like to do now is load the array with data (12 drugs x 5 fields) at runtime before the window opens.  The initial goal being to load a combo box with cri
Title: sorry for the double post!
Post by: iaNac on October 04, 2006, 02:43:07 AM
uh, how'd that happen?  Sorry
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: PBrennick on October 04, 2006, 05:28:57 AM
iaNac,
You need to post the code.  Are we supposed to guess what mistakes you have made.  I could have fun with that!  Seriously, help us help you.

Are you familiar with FPU coding?  You will need to be.  There is a nice FPU library in masm32.

Paul
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: Ratch on October 04, 2006, 06:24:54 AM
iaNac,

     Here is something to get you started.  The REAL4 word is 4 bytes long, just like the DWORD is.  It is interpreted in a particular way.  Read up on the FPU to get the format and operational details.  The code shows one way you can reference the 10 element of the array.  Ratch

[attachment deleted by admin]
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: sinsi on October 04, 2006, 06:45:05 AM
Are you going to do calculations with those REAL4s? If not, just store them as strings too.
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: iaNac on October 05, 2006, 01:18:41 PM
sinsi - yes, I'll need to do calculations.
Ratch - thanks for the zip (I'll look at it later - gotta get a root canal now)
PBrennick - sorry, I was trying to be conservative in my use of forum space.  How's everybody
get code to show in a grey box?

Here's more code as requested (WinMain).  I have made a few changes with no real progress.
Excuse all the comments, I'm still learning many basics.  I trimmed stuff out leaving this:

.486
.model flat,stdcall
option casemap:none

include iaNac32.inc ; windows,macros,masm32,gdi,user32,kernel32,Comctl

; PROTO section
    RegWinClass     PROTO :DWORD,:DWORD,:DWORD
    WinMain         PROTO :DWORD,:DWORD,:DWORD,:DWORD
    CreateComboBox  PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
    cbMsgInterp     PROTO :DWORD,:DWORD,:DWORD,:DWORD
    LoadCombo1      PROTO
    LoadCombo2      PROTO
    LoadCombo3      PROTO

; Structures
    CRI struct
        ; DrugForm  BYTE 32 dup (" ")
        DrugForm  DWORD   ?     ; (sas) ex. "Propofol 10.0 mg/ml"
        DrugDose  REAL4   ?     ; ex. 0.05
        ; DrugUnits BYTE 12 dup (" ")
        DrugUnits DWORD   ?     ; (sas) ex. "mg/kg/min"
        FluidRate REAL4   ?                     ; ex. 15.4         (ml/hr)
        FluidVol  DWORD   ?                     ; (sas) ex. 1000   (ml)
    CRI ends

; OMITTED: .DATA  .DATA?  .CONST and MACROS

.CODE   ; code section
start:

; get handles...
mov hInstance,FUNC(GetModuleHandle, NULL)       ; get handle to this program
mov CommandLine,FUNC(GetCommandLine)           ; get handle to CommandLine
mov hIcon, FUNC(LoadIcon,hInstance,MyIcon)       ; if MyIcon resource exists
mov hCursor,FUNC(LoadCursor,NULL,IDC_ARROW)  ; get handle to hCursor

; set variables...
mov bkgColor, COLOR_BTNFACE+1                ; set background color

; direct program flow to WinMain Loop...
invoke InitCommonControls
invoke WinMain,hInstance,NULL,CommandLine,WS_OVERLAPPEDWINDOW
; WinMain Loop is complete...
invoke ExitProcess, eax                      ; TERMINATE PROGRAM

; ««««««««««««««««««««««««««« WinMain Code Loop ««««««««««««««««««««««««««««

WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
LOCAL     msg:MSG
LOCAL      wc:WNDCLASSEX                     ; setup wc.WNDCLASSEX array
LOCAL   cri[11]:CRI

; ************************
; ** Problem area below **
; ************************

    ; >>>>> Store Drug Formulations...
    sas cri[0].DrugForm, "Lidocaine 2%"

    ; I think .DrugForm is still empty so sas probably wasn't right

    sas cri[1].DrugForm, "Metoclopramide 5.0 mg/ml"
    sas cri[2].DrugForm, "Procainamide 500.0 mg/ml"
    sas cri[3].DrugForm, "Propofol 10.0 mg/ml"
    ;fn MessageBox,hWnd,cri[0].DrugForm,"DrugForm",MB_OK ; CRASHES
    ;PrintStringByAddr cri[1].DrugForm       ; VKDebug returns no value
    ;PrintString cri[1].DrugForm                 ; VKDebug returns trash
    ;mov eax, cri[0].DrugForm                   ; mov pointer into eax?
    ;PrintDec eax                                     ; VKDebug returns 284481737
    ;PrintStringByAddr eax                        ; VKDebug returns no value
    ;mov eax, [cri[0].DrugForm]                ; mov pointer into eax?
    ;PrintDec eax                                    ; VKDebug returns 284481737

    ; >>>>> Store Drug Doses... (real4) also see code at Store Fluid Rates
    ; Data examples... Lido = 60.0, meto 1.0, procain 20.0, propofol 0.05
    mov eax, 60
    mov cri[0].DrugDose, eax ; would work if .DrugDose was DWORD
    ;fn MessageBox,hWnd,cri[0].DrugDose,"DrugDose",MB_OK ; CRASHES
    ;attempting real number...
    ;mov eax, 0.05 ; =====> error A2050: real or BCD number not allowed
    ;mov cri[0].DrugDose, 0.05 ; =====> error A2050

    ; >>>>> Store Drug Units...
    sas cri[0].DrugUnits, "mcg/kg/min"
    sas cri[1].DrugUnits, "mg/kg/day"
    sas cri[2].DrugUnits, "mcg/kg/min"
    sas cri[3].DrugUnits, "mg/kg/min"
    ;fn MessageBox,hWnd,cri[0].DrugUnits,"DrugUnit",MB_OK ; CRASHES

    ; >>>>> Store Fluid Rates... (real4)
    ; (bwKG default = 10 KG so (30xKG)+70=370ml / 24hr = 15.4 ml/hr)
    mov NumOfDrugs, 4                ; expand to 12 drugs later
    mov ecx, NumOfDrugs             ; also used in Store Fluid Volumes
    ;mov eax, 15.4 ; =====> error A2050
    mov esi, 0
    @@:
        mov cri[esi].FluidRate, eax
        ; PrintDec esi, "Fluid Rate Loop"
        inc esi
        cmp esi, ecx
        jne @B
    ;fn MessageBox,hWnd,cri[0].FluidRate,"FluidRate",MB_OK ; untested
    ;fn MessageBox,hWnd,cri[1].FluidRate,"FluidRate",MB_OK ; untested
    ;fn MessageBox,hWnd,cri[2].FluidRate,"FluidRate",MB_OK ; untested
    ;fn MessageBox,hWnd,cri[3].FluidRate,"FluidRate",MB_OK ; untested

    ; >>>>> Store Fluid Volumes...
    mov ecx, NumOfDrugs             ; still 4
    mov eax, 1000                       ; 1 liter default for all drugs
    mov esi, 0
    @@:
        mov cri[esi].FluidVol, eax
        ; PrintDec esi, "Fluid Vol Loop"
        inc esi
        cmp esi, ecx
        jne @B
    ;fn MessageBox,hWnd,cri[3].FluidVol,"FluidVol",MB_OK ; CRASHES

; ************************
; ** Problem area above **
; ************************

    ; register window's class...
    mov wc.cbSize,                 sizeof WNDCLASSEX
    mov wc.style,                   CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    m2m wc.lpfnWndProc,       OFFSET WinProc   ; hWin uMsg handler
    mov wc.cbClsExtra,           NULL
    mov wc.cbWndExtra,        NULL
    m2m wc.hInstance,           hInstance
    m2m wc.hbrBackground,    bkgColor
    mov wc.lpszMenuName,     OFFSET MenuName
    m2m wc.lpszClassName,     OFFSET szClassName
    m2m wc.hIcon,                hIcon
    m2m wc.hIconSm,           hIcon
    m2m wc.hCursor,             hCursor
    invoke RegisterClassEx,     ADDR wc

    ; get window centering coordinates...
    CenterWindow 225, 175 ; returns ctr.overX, ctr.downY, ctr.wWid, ctr.wHgt

    ; create window to specs...
    invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,
        ADDR szClassName,
        ADDR szAppTitle,
        CmdShow,
        ctr.overX,ctr.downY,ctr.wWid,ctr.wHgt,
        NULL,NULL,
        hInst,NULL
        mov hWnd,eax                            ; get handle to main window

    ; display the window...
    invoke ShowWindow,hWnd,SW_SHOWNORMAL        ; display window on desktop
    invoke UpdateWindow,hWnd                                  ; repaint the client area

    ; Loop until PostQuitMessage is sent...
    .WHILE TRUE                                             ; Enter message loop
    invoke GetMessage, ADDR msg,NULL,0,0        ; wait for, then get uMsg
    .BREAK .IF (!eax)                                        ; break if PostQuitMessage
        invoke TranslateMessage, ADDR msg          ; send key ASCII to WM_CHAR
            ; perform key processing here
        invoke DispatchMessage, ADDR msg           ; send uMsg to WinProc
    .ENDW
    mov eax,msg.wParam           ; return exit code in eax (rarely useful?)
    ret
WinMain endp                         ; end WinMain code loop, ready to terminate

; ««««««««««««««««««««««««««««««« PROCEDURES «««««««««««««««««««««««««««««««

; OMITTED: WinProc, CreateComboBox, cbMsgInterp, LoadCombo1,
; LoadCombo2, LoadCombo3, rsrc.rc

end start   ; end of code section
Title: Re: Please help... newbie problem...
Post by: Draakie on October 05, 2006, 02:35:13 PM
Hi iaNac,

I was very tempted to look at u're code / look again / and then run away as fast as possible. :lol

[ The Right Tools to start your'e discovery of Assembler Programming is required]


1.  Have a good look at the MASM32.lib - and it's companion help files
     the Zero Terminated String functions especially [EX:] szCatStr, szCopy
2. Get hold of the WIN32.hlp from the Forum-LINKS  - and all your'e API
    function calls are explained in detail [EX:] MessageBox
3. [PBrennick] was right - that FpuLib in MASM32 pack - is gonna help
    you LOTS - FPU programming is'nt something you just want to dive
    into.

Yes, the other Members in the Forum are probably going to help you with the
code you just posted. (Some are very brave souls indeed) . But if you are
going to learn this stuff - you've gotta walk the inch - we'll drag you the mile.

Draakie's Hubby
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: iaNac on October 05, 2006, 04:21:45 PM
Draakie - Thanks.  I think I'm going about learning asm in an odd way.  I bought Irving's book which recommended TextPad as an editor so that's what I started with.  I have masm32 downloaded but I linked its help files to TextPad but overlooked masm32 Lib Help so I really appreciate your post.  I've already written this program in VB but it may not have been the best choice as a second asm program.   I'm obviously not ready for fpu stuff yet so this may be over my head but I'll keep pounding away.  Thanks again!
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: PBrennick on October 05, 2006, 04:41:47 PM
iaNac,
Here is an idea.  You said that you have already written this program in VB so why don't you compile it in debug mode so you can look at a meaningful dissassembly using OllyDbg.  Using this method, you can examine how VB dealt with some of the more difficult portions of your code.  Let us know if this is revealing.

To get your code into a gray box you click the code button which is one of the buttons above the smilies, the one with the # on it. It will put two tags into the post, just paste your code between the two tags.  You can click the preview button to see how you are doing and it will show you what we will see and then the

Paul
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: iaNac on October 06, 2006, 12:35:03 AM
Ratch - I took a look at your zip file and I really appreciate your time.  It will help me a lot!

PBrennick - I like that idea, unfortunately the CRI routine was a small component of a much larger program.  I might have trouble picking out the CRI from the rest.  I've played with OllyDbg only a little.  Does "compile it in debug mode" mean the same thing as dissassembling the .exe?  (It doesn't sound like it.)

iaNac
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: Draakie on October 06, 2006, 06:36:53 AM
Quote from: iaNac on October 05, 2006, 04:21:45 PM
Draakie - Thanks.  I think I'm going about learning asm in an odd way.  I bought Irving's book which recommended TextPad as an editor so that's what I started with. 

Ouch ! - Please have a look at RADASM by KetilO
(A very nice IDE - mnemonic, API etc. highlighting and loads, loads, loads more.)

A good IDE will make life simpler and would probably make you feel more comfortable
coming from a VB back-ground.

Draakie
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: drizz on October 06, 2006, 10:24:47 AM
i can see some errors right away

>> LOCAL   cri[11]:CRI

when accessing such variables you must manually calculate offset,
masm doesnt auto calc it for you as HLLs do, it treats it as byte.

that is, instead of writing:

mov eax,cri[0].INeedDrugs
mov eax,cri[1].INeedDrugs

you must use:

mov eax,cri[0*(SIZEOF CRI)].INeedDrugs
mov eax,cri[1*(SIZEOF CRI)].INeedDrugs



assigning  a string:
.data
szDrug db "Andol",0
.code
invoke lstrcpy,addr cri[0*(SIZEOF CRI)].DrugForm,addr szDrug

Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: PBrennick on October 06, 2006, 12:08:15 PM
drizz,
I fail to see how that could be right.  He is creating an array of 11 pointers.  Your method would result in all calculations except 0 being outside the array.  Please explain.

Paul
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: sinsi on October 06, 2006, 12:28:31 PM
I think that if you use locals in your WinMain, nothing can see it -
LOCAL cri[11]:CRI

A couple of ideas:
- declare them in the .const section
- load them from a file into an allocated block
    - this will give you the option of a "user-modifiable" file maybe...
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: Ratch on October 06, 2006, 02:03:27 PM
iaNac,

     I should be whipped with a wet noodle for writing such bad code.  The following

MOV ESI,CRI                       ;ESI=size of CRI structure
SHL ESI,3                         ;ESI=8 times CRI structure
ADD ESI,CRI+@ Prescription        ;ESI=address of 10th element of array


should be replaced by

MOV ESI,9*CRI+@ Prescription      ;ESI=address of 10th element of array

  My apologies.
Ratch
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: PBrennick on October 06, 2006, 02:15:09 PM
Ratch,
That looks right to me, also.  I think that was what drizz was trying to do.

Paul
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: drizz on October 06, 2006, 02:18:57 PM
Quote from: PBrennick on October 06, 2006, 12:08:15 PMI fail to see how that could be right.  He is creating an array of 11 pointers.  Your method would result in all calculations except 0 being outside the array.  Please explain.
He is creating an array of 11 structures, not 11 structure pointers.
"LOCAL   cri[11]:PTR CRI" would be 11 structure pointers.
When accessing elements of an array calculation for offset must be done
because square brackets in asm dont have the same meaning as square brackets in HLLs.

Step By Step Examples:
byte array
local barray[100]:byte
mov al,barray[1*(sizeof byte)]
mov al,barray[2*(sizeof byte)]

optionally instead of "*sizeof byte" you can use "*TYPE barray"

word array
local warray[100]:word
mov ax,warray[1*(sizeof word)]
mov ax,warray[2*(sizeof word)]

optionally instead of "*sizeof word" you can use "*TYPE warray"

dword array
local dwarray[100]:dword
mov eax,dwarray[1*(sizeof dword)]
mov eax,dwarray[2*(sizeof dword)]

optionally instead of "*sizeof dword" you can use "*TYPE dwarray"

struct array
local structarray[100]:SOMESTRUCT
mov eax,structarray[1*(sizeof SOMESTRUCT)].element
mov eax,structarray[2*(sizeof SOMESTRUCT)].element

optionally instead of "*sizeof SOMESTRUCT" you can use "*TYPE structarray"


Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: drizz on October 06, 2006, 02:26:04 PM
for accessing structure elements in a loop:
; >>>>> Store Fluid Volumes...
xor ecx,ecx
xor esi,esi
mov eax,1000       ; 1 liter default for all drugs
.while ecx<NumOfDrugs ; still 4
; PrintDec ecx, "Fluid Vol Loop"
mov cri[esi].FluidVol, eax
add esi,sizeof CRI
.endw
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: Ratch on October 06, 2006, 06:31:24 PM
drizz,

     You don't need to use 'sizeof' or 'type' all the time.  If you want to code the size of a byte, you can code MOV AL,5*BYTE instead of MOV AL,5*(sizeof byte)] .  Similiarly, 2*(size of SOMESTRUCT) can be coded as 2*SOMESTRUCT.  Ratch
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: drizz on October 06, 2006, 06:51:09 PM
i somehow knew you would write that :), Yes i know (i just forgot to write the third option).
its my personal preference to use sizeof, as i use it in C,C++ too.
everyone his own  :P
Title: Re: Please help... newbie problems loading struct array with mixed data types
Post by: iaNac on October 07, 2006, 11:56:39 PM
Ratch - I finally had time to study your example and found it extremely helpful.  I got a lot out of it!

Thanks again - iaNac