News:

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

Calling from a proc

Started by bcddd214, October 25, 2011, 08:09:52 PM

Previous topic - Next topic

bcddd214

Here is the compile output.

Assembling: flipTest4.asm
flipTest4.asm(9) : error A2006: undefined symbol : LPSTR
flipTest4.asm(9) : error A2195: parameter or local cannot have void type
flipTest4.asm(9) : error A2129: VARARG parameter must be last parameter
flipTest4.asm(9) : error A2006: undefined symbol : UINT
flipTest4.asm(9) : error A2131: VARARG parameter requires C calling convention
flipTest4.asm(10) : error A2006: undefined symbol : LPSTR
flipTest4.asm(10) : error A2195: parameter or local cannot have void type
flipTest4.asm(10) : error A2131: VARARG parameter requires C calling convention
flipTest4.asm(11) : error A2006: undefined symbol : LPSTR
flipTest4.asm(11) : error A2195: parameter or local cannot have void type
flipTest4.asm(11) : error A2131: VARARG parameter requires C calling convention
flipTest4.asm(29) : error A2006: undefined symbol : LPSTR
flipTest4.asm(29) : error A2195: parameter or local cannot have void type
flipTest4.asm(29) : error A2111: conflicting parameter definition
flipTest4.asm(58) : error A2005: symbol redefinition : lpszString
flipTest4.asm(58) : error A2111: conflicting parameter definition
flipTest4.asm(88) : error A2005: symbol redefinition : lpszString
flipTest4.asm(88) : error A2111: conflicting parameter definition
flipTest4.asm(128) : error A2114: INVOKE argument type mismatch : argument : 2
flipTest4.asm(128) : error A2114: INVOKE argument type mismatch : argument : 1
flipTest4.asm(129) : error A2114: INVOKE argument type mismatch : argument : 1
flipTest4.asm(38) : error A2006: undefined symbol : epb
Press any key to continue . . .

bcddd214

I would love a response to this post. I really have things broken down in a manner I can understand them (at this point). Your later posting are probably correct but my brain will be able to comfortably twist to your side of the force once I understand where I am at here.
at line 41, I have disabled swapit. I am trying find out if I am where I need to be at this point before trying to figure out 'why' my handoff to swapit is jacked.  :)

Quote from: bcddd214 on November 03, 2011, 11:04:25 PM
In this format the programs is up to specs from what I understand except for the flip action is disabled.
In this format the registers are protected and it reads and counts the number of string.
The only thing to do at this point is implement the flip proc from StringLength or uncommenting line 41.

But she hangs if I do?

****************************
        TITLE   FlipTest
        INCLUDE Irvine32.inc

;################################################

        .DATA

Mes1    BYTE "Enter a 5 digit string: ",0
InName  BYTE 6 dup(0)

;################################################

        .CODE

;************************************************

GetInput PROC

        push    edx
        mov     edx, eax
        call    WriteString
        pop     edx
        call    ReadString
        ret

GetInput ENDP

;************************************************

StringLength PROC
      push    ebp
      mov      ebp, esp
        push    edi
        mov     al, 0
        or      ecx, -1
        mov     edi, [ebp+8]
        repnz   scasb
        neg     ecx
        sub     ecx, 2
      mov      eax, ecx
;      call   SwapIt
        pop     edi
      pop      ebp
        ret   4

StringLength ENDP

;************************************************

SwapIt  PROC
        push    ebp
      mov     ebp, esp
        push    eax
        push    ecx
        push    edx      
      push    [ebp + 8]
;      call    StringLength
      mov      ecx, eax
        dec     ecx      
        add     ecx, edx
        jmp short SwpIt1

SwpIt0: mov     al, [edx]
        mov     ah, [ecx]
        mov     [ecx], al
        mov     [edx], ah
        dec     ecx
        inc     edx

SwpIt1: cmp     ecx, edx
        ja      SwpIt0

        pop     edx
        pop     ecx
        pop     eax
      pop     ebp
        ret

SwapIt  ENDP

;************************************************

Main    PROC

        mov     eax, offset Mes1
        mov     edx, offset InName
        mov     ecx, sizeof InName
        call    GetInput

      push    OFFSET InName
;        call    SwapIt
      call   StringLength
      call   writedec
        call    WriteString
        call    Crlf
        exit

Main    ENDP

;################################################

        END     Main

jj2007

Hi,
I don't have the Irvine package but managed to "emulate" it partially. Here is what I found...

QuoteSwapIt PROC
   push ebp
   mov ebp, esp
   push eax
   push ecx
   push edx
   push [ebp + 8]
   push edx
;   call StringLength   ; calls SwapIt, not possible
   mov eax, len(eax)   ; Masm32 substitute
   pop edx
   mov ecx, eax
   dec ecx
   add ecx, edx
   jmp short SwpIt1

SwpIt0:   mov al, [edx]
   mov ah, [ecx]
   mov [ecx], al
   mov [edx], ah
   dec ecx
   inc edx

SwpIt1:   cmp ecx, edx
   ja SwpIt0
   pop edx   ; YOUR STACK IS NOT BALANCED
   pop edx
   pop ecx
   pop eax
   pop ebp
   ret
SwapIt ENDP

dedndave

ok - let's try this again.....
        TITLE   FlipTest

;################################################

        INCLUDE Irvine32.inc

;################################################

GetInput     PROTO :DWORD, :DWORD, :DWORD
StringLength PROTO :DWORD
SwapIt       PROTO :DWORD

;################################################

        .DATA

Mes1    BYTE "Enter a 5 digit string: ", 0
InName  BYTE 6 dup(0)

;################################################

        .CODE

;************************************************

        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

GetInput PROC   lpszString:DWORD, lpBuffer:DWORD, uLength:DWORD

;Call With: lpszString = pointer to message string
;             lpBuffer = pointer to input buffer
;              uLength = length of input buffer
;
;  Returns: buffer is filled with user input
;           ECX, EDX are destroyed

        push    ebp
        mov     ebp, esp
        mov     edx, [ebp+8]          ;lpszString
        call    WriteString
        mov     edx, [ebp+12]         ;lpBuffer
        mov     ecx, [ebp+16]         ;uLength
        call    ReadString
        pop     ebp
        ret     12                    ;return and discard 3 dwords

GetInput ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

;************************************************

        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

StringLength PROC lpszString:DWORD

;Call With: lpszString = pointer to null-terminated string
;
;  Returns: EAX = string length
;           ECX is destroyed

        push    edi
        push    ebp
        mov     ebp, esp
        mov     al, 0
        or      ecx, -1
        mov     edi, [ebp+12]         ;lpszString
        repnz   scasb
        or      eax, -2
        sub     eax, ecx
        pop     ebp
        pop     edi
        ret     4                     ;return and discard 1 dword

StringLength ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

;************************************************

        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

SwapIt  PROC    lpszString:DWORD

;Call With: lpszString = pointer to null-terminated string
;
;  Returns: string is reversed
;           EDX = pointer to reversed string
;           EAX, ECX are destroyed

        push    ebp
        mov     ebp, esp
        INVOKE  StringLength, [ebp+8]
        mov     edx, [ebp+8]          ;lpszString
        dec     eax
        push    edx
        add     eax, edx
        jmp short SwpIt1

SwpIt0: mov     cl, [edx]
        mov     ch, [eax]
        mov     [eax], cl
        mov     [edx], ch
        dec     eax
        inc     edx

SwpIt1: cmp     eax, edx
        ja      SwpIt0

        pop     edx
        pop     ebp
        ret     4                     ;return and discard 1 dword

SwapIt  ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

;************************************************

Main    PROC

        INVOKE  GetInput, offset Mes1, offset InName, sizeof InName
        INVOKE  SwapIt, offset InName
        call    WriteString
        call    Crlf
        exit

Main    ENDP

;################################################

        END     Main

bcddd214

Thank you for your reply!
#1  Why is it not possible to call on stinglength from swap it? I think you are hitting on a note that a colleague purposely put me into this trap in order to get and understanding of while we push a pop at the beginning to force the proper passing of safe data through bp. I might be wrong for a reason and would enjoy knowing why.

#2 Stack not balanced? Can you explain my friend?

Quote from: jj2007 on November 26, 2011, 07:36:00 PM
Hi,
I don't have the Irvine package but managed to "emulate" it partially. Here is what I found...

QuoteSwapIt PROC
   push ebp
   mov ebp, esp
   push eax
   push ecx
   push edx
   push [ebp + 8]
   push edx
;   call StringLength   ; calls SwapIt, not possible
   mov eax, len(eax)   ; Masm32 substitute
   pop edx
   mov ecx, eax
   dec ecx
   add ecx, edx
   jmp short SwpIt1

SwpIt0:   mov al, [edx]
   mov ah, [ecx]
   mov [ecx], al
   mov [edx], ah
   dec ecx
   inc edx

SwpIt1:   cmp ecx, edx
   ja SwpIt0
   pop edx   ; YOUR STACK IS NOT BALANCED
   pop edx
   pop ecx
   pop eax
   pop ebp
   ret
SwapIt ENDP

jj2007

#1  Why is it not possible to call on stinglength from swap it?
Because you would enter an endless loop: a calls b calls a calls b calls a calls....

#2 Stack not balanced? Can you explain my friend?
You are pushing more than you pop. As a result, the return address is not where the ret expects it, and your ret ends up in no man's land.

You should consider using a debugger, e.g. OllyDbg. It helps a lot to see where the crash happens...

bcddd214

My logic should be fixed but she still hangs.
line 59 which commented now for debugging but should have fixed my balance error when implemented does not.


        TITLE   FlipTest
        INCLUDE Irvine32.inc

;################################################

        .DATA

Mes1    BYTE "Enter a 5 digit string: ",0
InName  BYTE 6 dup(0)

;################################################

        .CODE

;************************************************

GetInput PROC

        push    edx
        mov     edx, eax
        call    WriteString
        pop     edx
        call    ReadString
        ret

GetInput ENDP

;************************************************

StringLength PROC
      push    ebp
      mov      ebp, esp
        push    edi
        mov     al, 0
        or      ecx, -1
        mov     edi, [ebp+8]
        repnz   scasb
        neg     ecx
        sub     ecx, 2
      mov      eax, ecx
;      call   SwapIt
        pop     edi
      pop      ebp
        ret   4

StringLength ENDP

;************************************************

SwapIt  PROC
        push    ebp
      mov     ebp, esp
        push    eax
        push    ecx
        push    edx      
      push    [ebp + 8]
;      call    StringLength
; new
;      pop edx
      mov      ecx, eax
        dec     ecx      
        add     ecx, edx
        jmp short SwpIt1

SwpIt0: mov     al, [edx]
        mov     ah, [ecx]
        mov     [ecx], al
        mov     [edx], ah
        dec     ecx
        inc     edx

SwpIt1: cmp     ecx, edx
        ja      SwpIt0

        pop     edx
        pop     ecx
        pop     eax
      pop     ebp
        ret

SwapIt  ENDP

;************************************************

Main    PROC

        mov     eax, offset Mes1
        mov     edx, offset InName
        mov     ecx, sizeof InName
        call    GetInput

      push    OFFSET InName
      call   StringLength
        call    SwapIt
      call   writedec
        call    WriteString
        call    Crlf
        exit

Main    ENDP

;################################################

        END     Main

bcddd214

This is brilliant. I am just breaking her down now.
What is "OPTION  PROLOGUE:PrologueDef"?


Quote from: bcddd214 on November 26, 2011, 07:51:41 PM
Thank you for your reply!
#1  Why is it not possible to call on stinglength from swap it? I think you are hitting on a note that a colleague purposely put me into this trap in order to get and understanding of while we push a pop at the beginning to force the proper passing of safe data through bp. I might be wrong for a reason and would enjoy knowing why.

#2 Stack not balanced? Can you explain my friend?

Quote from: jj2007 on November 26, 2011, 07:36:00 PM
Hi,
I don't have the Irvine package but managed to "emulate" it partially. Here is what I found...

QuoteSwapIt PROC
   push ebp
   mov ebp, esp
   push eax
   push ecx
   push edx
   push [ebp + 8]
   push edx
;   call StringLength   ; calls SwapIt, not possible
   mov eax, len(eax)   ; Masm32 substitute
   pop edx
   mov ecx, eax
   dec ecx
   add ecx, edx
   jmp short SwpIt1

SwpIt0:   mov al, [edx]
   mov ah, [ecx]
   mov [ecx], al
   mov [edx], ah
   dec ecx
   inc edx

SwpIt1:   cmp ecx, edx
   ja SwpIt0
   pop edx   ; YOUR STACK IS NOT BALANCED
   pop edx
   pop ecx
   pop eax
   pop ebp
   ret
SwapIt ENDP

bcddd214

I don't think 'or' is a directive is it?
one of the tricks to this is I can't use any directives like 'if'.

Quote from: dedndave on November 26, 2011, 07:38:17 PM
ok - let's try this again.....
        TITLE   FlipTest

;################################################

        INCLUDE Irvine32.inc

;################################################

GetInput     PROTO :DWORD, :DWORD, :DWORD
StringLength PROTO :DWORD
SwapIt       PROTO :DWORD

;################################################

        .DATA

Mes1    BYTE "Enter a 5 digit string: ", 0
InName  BYTE 6 dup(0)

;################################################

        .CODE

;************************************************

        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

GetInput PROC   lpszString:DWORD, lpBuffer:DWORD, uLength:DWORD

;Call With: lpszString = pointer to message string
;             lpBuffer = pointer to input buffer
;              uLength = length of input buffer
;
;  Returns: buffer is filled with user input
;           ECX, EDX are destroyed

        push    ebp
        mov     ebp, esp
        mov     edx, [ebp+8]          ;lpszString
        call    WriteString
        mov     edx, [ebp+12]         ;lpBuffer
        mov     ecx, [ebp+16]         ;uLength
        call    ReadString
        pop     ebp
        ret     12                    ;return and discard 3 dwords

GetInput ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

;************************************************

        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

StringLength PROC lpszString:DWORD

;Call With: lpszString = pointer to null-terminated string
;
;  Returns: EAX = string length
;           ECX is destroyed

        push    edi
        push    ebp
        mov     ebp, esp
        mov     al, 0
        or      ecx, -1
        mov     edi, [ebp+12]         ;lpszString
        repnz   scasb
        or      eax, -2
        sub     eax, ecx
        pop     ebp
        pop     edi
        ret     4                     ;return and discard 1 dword

StringLength ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

;************************************************

        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

SwapIt  PROC    lpszString:DWORD

;Call With: lpszString = pointer to null-terminated string
;
;  Returns: string is reversed
;           EDX = pointer to reversed string
;           EAX, ECX are destroyed

        push    ebp
        mov     ebp, esp
        INVOKE  StringLength, [ebp+8]
        mov     edx, [ebp+8]          ;lpszString
        dec     eax
        push    edx
        add     eax, edx
        jmp short SwpIt1

SwpIt0: mov     cl, [edx]
        mov     ch, [eax]
        mov     [eax], cl
        mov     [edx], ch
        dec     eax
        inc     edx

SwpIt1: cmp     eax, edx
        ja      SwpIt0

        pop     edx
        pop     ebp
        ret     4                     ;return and discard 1 dword

SwapIt  ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef

;************************************************

Main    PROC

        INVOKE  GetInput, offset Mes1, offset InName, sizeof InName
        INVOKE  SwapIt, offset InName
        call    WriteString
        call    Crlf
        exit

Main    ENDP

;################################################

        END     Main


jj2007

Quote from: bcddd214 on November 26, 2011, 11:30:53 PM
This is brilliant. I am just breaking her down now.
What is "OPTION  PROLOGUE:PrologueDef"?

It means "insert a stack frame if needed" and is the default mode, so you don't have to specify it. You are doing it "by hand" with the push ebp/pop ebp sequence, by the way: without any need and without any effect. You will have to take that off, and use the none directives instead of the Def ones, in combination with retn 4.
My advice: RTFM.

dedndave

i don't think you can write much of a program without using directives
TITLE, INCLUDE, PROTO, .DATA, BYTE, .CODE, OPTION, PROC, ENDP, and END are all directives
others are necessary that are in Irvine32.inc, like .MODEL

perhaps what is meant is "you can't use any conditional directives", like IF

the OPTION Prologue and OPTION Epilogue directives are used to control the way the assembler creates PROCS

if there are any parameters on the PROC line, or if there are any local variables, the assembler generates
a prologue at the beginning of the PROC and an epilogue anywhere a RET appears

we want to write our own so that we can see PUSH EBP, POP EBP, etc in our code
if we do not turn them off with OPTION, the assembler generates code we do not see in the source

OR is an instruction - not a directive
        or      eax, -2

OR can also be an operator, but not in that case
here, we see it used as an operator
SOME_CONSTANT EQU 6 or 14

dedndave

the way OR is used in the StringLength PROC, it could be replaced with MOV
        mov     ecx, -1
        mov     edi, [ebp+12]         ;lpszString
        repnz   scasb
        mov     eax, -2


by using OR, it saves 2 bytes in each case

bcddd214

already read the manual, this is the practical app after.
If it's all the same and possible, I rather do both just to tick a third party whom is breathing down my next for gross overkill.
I know I am doing both and I only need one but I also know why both are there and it is in the interest of gross overkill.

Quote from: jj2007 on November 26, 2011, 11:39:23 PM
Quote from: bcddd214 on November 26, 2011, 11:30:53 PM
This is brilliant. I am just breaking her down now.
What is "OPTION  PROLOGUE:PrologueDef"?

It means "insert a stack frame if needed" and is the default mode, so you don't have to specify it. You are doing it "by hand" with the push ebp/pop ebp sequence, by the way: without any need and without any effect. You will have to take that off, and use the none directives instead of the Def ones, in combination with retn 4.
My advice: RTFM.

dedndave

one way to learn about stack frames (EBP, prologues, epilogues) is to look at a few routines written both ways
a while back, i made a couple posts on this subject.....

http://www.masm32.com/board/index.php?topic=15307.msg124847#msg124847

http://www.masm32.com/board/index.php?topic=14381.msg114921#msg114921

you can also read the documentation in the MASM reference manual....

http://www.4shared.com/file/39MdNf_v/MASMProgGuide.html