I have this program and trying to change the calling in stringLength instead of calling from main and getting some wild errors
Line 54 is what I moved.
Title flipTest
INCLUDE Irvine32.inc
;################################################
SwapIt PROTO :DWORD,:DWORD
stringLengthProc PROTO :DWORD
;################################################
.data
mes1 BYTE "Enter a 5 digit string: ",0
inName DWORD 3 dup(0)
math1 BYTE 2
lpString:DWORD
dwLength:DWORD
;################################################
.code
;************************************************
getNameProc PROC
push edx
mov edx,offset mes1
call WriteString
mov edx,offset inName
mov ecx, sizeof inName
call ReadString
pop edx
ret
getNameProc ENDP
;************************************************
stringLengthProc PROC lpString:DWORD
;returns the string length in EAX
push ecx
push edi
mov al,0
or ecx,-1
mov edi,lpString
repnz scasb
or eax,-2
sub eax,ecx
pop edi
pop ecx
call SwapIt offset inName,eax
ret
stringLengthProc ENDP
;************************************************
SwapIt PROC
push ecx
push edx
mov ecx,dwLength
mov edx,lpString
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
ret
SwapIt ENDP
;************************************************
main PROC
call getNameProc
INVOKE stringLengthProc,offset inName
; INVOKE SwapIt,offset inName,eax
mov edx,offset inName
call WriteString
call Crlf
exit
main ENDP
;################################################
END main
Why do you believe that the assembler should understand call SwapIt offset inName,eax ?
i would be surprised if it assembles :P
call SwapIt offset inName,eax
you are trying to convert a process that has paramaters on the stack to one that does not
to be tidy, let's reorganize things a bit
notice how the SwapIt proc now calls StringLength, so it is "self-contained"
made a few other changes to make it easier to read :P
TITLE FlipTest
INCLUDE Irvine32.inc
;################################################
.DATA
Mes1 BYTE "Enter a 5 digit string: ",0
InName BYTE 6 dup(0)
;################################################
.CODE
;************************************************
GetInput PROC
;Call With: EAX = address displayed string
; EDX = address of input buffer
; ECX = size of input buffer
;
; Returns: buffer filled with user input
; all registers are preserved
push edx
mov edx, eax
call WriteString
pop edx
call ReadString
ret
GetInput ENDP
;************************************************
StringLength PROC
;Call With: EDX = address of string
;
; Returns: ECX = length of string, less null terminator
; all other registers preserved
push eax
push edi
mov al, 0
or ecx, -1
mov edi, edx
repnz scasb
neg ecx
sub ecx, 2
pop edi
pop eax
ret
StringLength ENDP
;************************************************
SwapIt PROC
;Call With: EDX = address of string to reverse
;
; Returns: string is reversed
; all registers are preserved
push eax
push ecx
push edx
call StringLength
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
ret
SwapIt ENDP
;************************************************
Main PROC
mov eax, offset Mes1
mov edx, offset InName
mov ecx, sizeof InName
call GetInput
call SwapIt
call WriteString
call Crlf
exit
Main ENDP
;################################################
END Main
EDIT: changed the proc called "GetName" to "GetInput" - makes more sense
the forum seems to want to remove a space from each line that starts with one, today - fixed that too
But SwapIt cannot occur in main. It has to be called from the 'StringLength PROC'???
it quits working like this
TITLE FlipTest
INCLUDE Irvine32.inc
;################################################
.DATA
Mes1 BYTE "Enter a 5 digit string: ",0
InName BYTE 6 dup(0)
;################################################
.CODE
;************************************************
GetInput PROC
;Call With: EAX = address displayed string
; EDX = address of input buffer
; ECX = size of input buffer
;
; Returns: buffer filled with user input
; all registers are preserved
push edx
mov edx, eax
call WriteString
pop edx
call ReadString
ret
GetInput ENDP
;************************************************
StringLength PROC
;Call With: EDX = address of string
;
; Returns: ECX = length of string, less null terminator
; all other registers preserved
push eax
push edi
mov al, 0
or ecx, -1
mov edi, edx
repnz scasb
neg ecx
sub ecx, 2
pop edi
pop eax
ret
StringLength ENDP
;************************************************
SwapIt PROC
;Call With: EDX = address of string to reverse
;
; Returns: string is reversed
; all registers are preserved
push eax
push ecx
push edx
call StringLength
call SwapIt
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
ret
SwapIt ENDP
;************************************************
Main PROC
mov eax, offset Mes1
mov edx, offset InName
mov ecx, sizeof InName
call GetInput
; call SwapIt
call WriteString
call Crlf
exit
Main ENDP
;################################################
END Main
i am afraid i do not understand what you are trying to accomplish
did the code work, as i posted it ?
what are you trying to do - be specific
I made some changes so my format is now correct but the program quit working.
I had to change over to work my counting out on the ecx register but this broke my swapping action. I tried to do a static flip back to the eax but mov'ing my data from ecx back to eax is not working.
Line 57 "should" be the point that the program passes my info back to eax and then carry on as normal.
Not sure what to do at this point.
***************************
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
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
ok - let's go back to the code in this post
http://www.masm32.com/board/index.php?topic=17611.msg148268#msg148268
at the beginning of each PROC, i made notes on what registers are passed, returned, and preserved
unless a value is returned in a specific register, i preserved it
there are exceptions to this - if the value in that register is no longer useful
read those notes carefully
the changes you made destroy the contents of ECX and maybe EDX, which were intended to be preserved
in my posted code - the values in those registers are used in the next call - maybe even the one after
and - a big problem - you do not want to CALL SwapIt inside the SwapIt PROC
that routine will not exit until the stack overflows :P
Calling SwapIt from within SwapIt is recursive programming.
You must test for an exit condition before you call it from within. Otherwise, you get the equivalent of an infinite loop - except it's now infinite recursion.
And just as you have to make sure that loops advance, you need to make sure each recursion involve some form of advancement, the next whatever, before calling it.
A count down loop
test ecx,ecx
xloop:
jz endxloop
push ecx
; ... work code here ...
pop ecx
dec ecx ; advance counter
jmp xloop
endxloop:
gets transformed to
xrecurse:
test ecx,ecx
jz endrecurse
push ecx
; ... work code here ...
pop ecx
dec ecx ; advance counter
call xrecurse
ret
endrecurse:
Recursion becomes more useful when dealing with tree structures and tree-like processing, such as walking through a directory tree.
:bg
i know what a recursive call is - and this isn't it
he has no need, nor intention, of using recursion
he is simply shuffling things around a bit, and accidently put the call inside the proc
But there it is - the rules for it :green2
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
?
try this - i did not test it :P
TITLE FlipTest
;################################################
INCLUDE Irvine32.inc
;################################################
GetInput PROTO :LPSTR, :LPSTR, :UINT
StringLength PROTO :LPSTR
SwapIt PROTO :LPSTR
;################################################
.DATA
Mes1 BYTE "Enter a 5 digit string: ", 0
InName BYTE 6 dup(0)
;################################################
.CODE
;************************************************
OPTION PROLOGUE:None
OPTION EPILOGUE:None
GetInput PROC lpszString:LPSTR, lpBuffer:LPSTR, uLength:UINT
;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 epb
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:LPSTR
;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:LPSTR
;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
the assembler will generate the same code as though you had written Main like this
;************************************************
Main PROC
push sizeof InName
push offset InName
push offset Mes1
call GetInput
push offset InName
call SwapIt
call WriteString
call Crlf
exit
Main ENDP
;################################################
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 . . .
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
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
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
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
#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 (http://www.ollydbg.de/version2.html). It helps a lot to see where the crash happens...
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
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
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
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 (http://www.urbandictionary.com/define.php?term=RTFM).
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
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
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 (http://www.urbandictionary.com/define.php?term=RTFM).
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