The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: StatusQuo on October 14, 2011, 12:59:23 AM

Title: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 14, 2011, 12:59:23 AM
Hello to all, I am fairly familiar with this forum and I was hoping to get some insight in on a particular program that I have written. The following program is written so that a user my enter a string, and that string is displayed with the result of counted characters within that string. I was wondering, using this same logic, WITHOUT Stacks, is it possible to take this program of mines, and simply modify it so that it could swap the first character with the last character and vice versa? At the moment I have not a single clue on how to begin to write such an experiment, only in plain English but mathematically, I do not know how to pursue it. So please if anyone could perhaps show me the way or enlighten me.  :bg



Include Irvine32.inc
.data
Var            BYTE 128 DUP(0)
String         BYTE "Enter A String To Be Swapped: "

.code
Strlen         PROC
            CALL      Clrscr
            MOV         EDX, OFFSET String
            CALL      WriteString
            
            MOV         EDX, OFFSET Var
            MOV         ECX, (SIZEOF Var)
            CALL      ReadString

EXIT
Strlen         ENDP

Strrev         PROC
            MOV         ECX,0
            MOV         BL, EDX
            CMP         BL,0




EXIT
Strrev         ENDP

MAIN         PROC
            CALL      Strlen
            CALL      Strrev
            
EXIT
MAIN         ENDP
            END         MAIN

Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 14, 2011, 02:35:38 AM
everytime you use CALL or RET, you are using the stack
and when you preserve registers, of course
you will have to write all "in-line" code in the main proc - lol

i just posted a routine to do that on another thread   :P
other than the CALL and parameter passing, it uses no stack
you guys must have the same instructor
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 15, 2011, 04:49:23 PM
Hey I just noticed that Thread, its a small world apprently. But thank you I just went into that thread and saw what you did. I guess that answers my question so far. I suppose I still have a bit of more studying to do.
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 21, 2011, 12:16:16 AM
So far I get the idea but my program is a little bit off. I am pulling my hair because I enter a string and instead of it giving it to my backwards, I recieved only a single String back. So far I have been trying to use the other program in the other thread as a template, but I suppose I want to make it as basic is possible. Here is my code, and I have a feeling I am missing something very basic in these elements. Thursdays *Sigh*. :eek

Include Irvine32.inc
.data
Var            BYTE 128 DUP(0)
Target         BYTE 0
String         BYTE "Enter A String To Be Swapped: "

.code
Strrev      PROC
         PUSH EDX
         MOV EDX, OFFSET String
         CALL WriteString
         MOV EDX, OFFSET Target
         MOV ECX,(SIZEOF Target)
         CALL ReadString
         POP EDX
         RET
         CALL Strlen
Strrev      ENDP

Strlen      PROC
         PUSH ECX
         PUSH EDX
         DEC ECX
         ADD ECX, EDX
         Jmp L1
L1:
         MOV AL, [EDX]
         MOV AH, [ECX]
         MOV [ECX], AL
         MOV [EDX], AH
         DEC ECX
         INC EDX
L2:
         CMP ECX, EDX
         JMP L1
         POP EDX
         POP ECX
         RET

Strlen      ENDP

MAIN       PROC
         CALL Strrev
         MOV EDX, OFFSET Target
         CALL WriteString
         CALL Crlf

EXIT
MAIN       ENDP
         END MAIN

[code/]

P.S i have no relations with the other guy. lol
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 21, 2011, 12:32:25 AM
well - i don't have Irvine32 set up
give me some time - i want to make a quicky masm32 equiv program
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 21, 2011, 12:36:02 AM
Strrev      PROC
         PUSH EDX
         MOV EDX, OFFSET String
         CALL WriteString
         MOV EDX, OFFSET Target
         MOV ECX,(SIZEOF Target)
         CALL ReadString
         POP EDX
         RET
         CALL Strlen
Strrev      ENDP


ok - this routine does not reverse the string   :P
also, the CALL Strlen instruction at the end will not be executed
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 21, 2011, 12:39:22 AM
Strlen      PROC
         PUSH ECX
         PUSH EDX
         DEC ECX
         ADD ECX, EDX
         Jmp L1
L1:
         MOV AL, [EDX]
         MOV AH, [ECX]
         MOV [ECX], AL
         MOV [EDX], AH
         DEC ECX
         INC EDX
L2:
         CMP ECX, EDX
         JMP L1
         POP EDX
         POP ECX
         RET

Strlen      ENDP


this routine is supposed to reverse the string ?
it does not get the length of the string   :P

also, if it is supposed to reverse the string...
         Jmp L1
should be
         Jmp L2
and
         JMP L1
should be
         JA  L1

it looks to me as though you used copy/paste and you ran with the scissors   :naughty:
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 21, 2011, 12:46:04 AM
Quote from: dedndave on October 21, 2011, 12:36:02 AM
Strrev      PROC
         PUSH EDX
         MOV EDX, OFFSET String
         CALL WriteString
         MOV EDX, OFFSET Target
         MOV ECX,(SIZEOF Target)
         CALL ReadString
         POP EDX
         RET
         CALL Strlen
Strrev      ENDP


ok - this routine does not reverse the string   :P
also, the CALL Strlen instruction at the end will not be executed


Sorry I had my names flip flopped, its the other way around, and I made an adjustment towrds the program.




Include Irvine32.inc
.data
Var            BYTE 128 DUP(0)
Target         BYTE 0
String         BYTE "Enter A String To Be Swapped: "

.code
Strrev      PROC
         PUSH ECX
         PUSH EDX
         DEC ECX
         ADD ECX, EDX
         Jmp L1
L1:
         MOV AL, [EDX]
         MOV AH, [ECX]
         MOV [ECX], AL
         MOV [EDX], AH
         DEC ECX
         INC EDX
L2:
         CMP ECX, EDX
         JMP L1
         POP EDX
         POP ECX
         RET
Strrev      ENDP

Strlen      PROC lpString:DWORD

         PUSH EDX
         MOV EDX, OFFSET String
         CALL WriteString
         MOV EDX, OFFSET Target
         MOV ECX,(SIZEOF Target)
         CALL ReadString
         POP EDX
         RET
         CALL Strrev

Strlen      ENDP

MAIN       PROC
         CALL Strlen
         MOV EDX, OFFSET Target
         CALL WriteString
         CALL Crlf
EXIT
MAIN       ENDP
         END MAIN
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 21, 2011, 12:49:17 AM
And No Dave, I just copy and past my original worked program here, I get lazy dude, sorry  :lol
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 21, 2011, 01:25:39 AM
give this a whirl
i was not able to test it - so let me know if it has bugs
        INCLUDE Irvine32.inc

;-----------------------------------------------------------

        .DATA

String  BYTE "Enter A String To Be Swapped: ",0

;--------------------------------

        .DATA?

Target  BYTE 128 DUP(?)

;-----------------------------------------------------------

        .CODE

StrRev  PROC

;Call With: EDX = address of string
;           ECX = length of string
;
;  Returns: string is reversed

        PUSH    EAX
        PUSH    ECX
        PUSH    EDX
        DEC     ECX
        ADD     ECX, EDX
        JMP     L2

L1:     MOV     AL, [EDX]
        MOV     AH, [ECX]
        MOV     [ECX], AL
        MOV     [EDX], AH
        DEC     ECX
        INC     EDX

L2:     CMP     ECX, EDX
        JA      L1

        POP     EDX
        POP     ECX
        POP     EAX
        RET

StrRev  ENDP

;-----------------------------------------------------------

StrLen  PROC

;Call With: EDX = address of string
;
;  Returns: ECX = length of string

        PUSH    EAX
        PUSH    EDI
        MOV     AL, 0
        MOV     EDI, EDX
        MOV     ECX, 0FFFFFFFFh
        REPNZ   SCASB
        NEG     ECX
        SUB     ECX,2
        POP     EDI
        POP     EAX
        RET

StrLen  ENDP

;-----------------------------------------------------------

MAIN    PROC

        MOV     EDX, OFFSET String
        CALL    WriteString
        MOV     EDX, OFFSET Target
        MOV     ECX, SIZEOF Target
        CALL    ReadString
        CALL    StrLen
        CALL    StrRev
        CALL    WriteString
        CALL    Crlf
        exit

MAIN    ENDP

;-----------------------------------------------------------

        END     MAIN
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 21, 2011, 02:07:21 AM
i just noticed the title of this thread   :bg
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: Gunner on October 21, 2011, 02:15:31 AM
Quote from: dedndave on October 21, 2011, 02:07:21 AM
i just noticed the title of this thread   :bg

Really, Really time for new glasses Dave :dazzled:
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: jj2007 on October 21, 2011, 02:40:54 AM
Hi StatusQuo,
Here is a working version of your StrRev procedure. Only minor adjustments were needed to make it run :U

StrRev PROC
         PUSH ECX
         PUSH EDX
         DEC ECX
         ADD ECX, EDX
;         Jmp L1   jump on itself makes no sense   
L1:
         MOV AL, [EDX]
         MOV AH, [ECX]
         MOV [ECX], AL
         MOV [EDX], AH
         DEC ECX
         INC EDX
; never used: L2:
         CMP ECX, EDX
         ja L1      ; conditional jump above
         POP EDX
         POP ECX
         RET
StrRev ENDP
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 21, 2011, 02:47:49 AM
hiyas Jochen

i put a branch here originally to L2
;         Jmp L1   jump on itself makes no sense
it performs the "are we done" test for strings that have a length of 0 or 1
StrRev  PROC

;Call With: EDX = address of string
;           ECX = length of string
;
;  Returns: string is reversed

        PUSH    EAX
        PUSH    ECX
        PUSH    EDX
        DEC     ECX
        ADD     ECX, EDX
        JMP     L2

L1:     MOV     AL, [EDX]
        MOV     AH, [ECX]
        MOV     [ECX], AL
        MOV     [EDX], AH
        DEC     ECX
        INC     EDX

L2:     CMP     ECX, EDX
        JA      L1

        POP     EDX
        POP     ECX
        POP     EAX
        RET

StrRev  ENDP
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 21, 2011, 02:51:45 AM
it could be done this way
however, the loop then executes an unnecessary JMP with each pass
        PUSH    EAX
        PUSH    ECX
        PUSH    EDX
        DEC     ECX
        ADD     ECX, EDX

L1:     CMP     ECX, EDX
        JBE     L2

        MOV     AL, [EDX]
        MOV     AH, [ECX]
        MOV     [ECX], AL
        MOV     [EDX], AH
        DEC     ECX
        INC     EDX
        JMP     L1

L2:     POP     EDX
        POP     ECX
        POP     EAX
        RET


my rule of thumb is...
if the loop ends in JMP, there is probably a better way
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: jj2007 on October 21, 2011, 05:28:12 AM
What about
  push edx
  dec ecx
  jle L2

...? Anyway, my favourite is this one:
FlipFlopP proc ; uses esi edi lpSrc=lpDest
  pop edx ; ret addr
  pop eax ; lpSrc, lpDest
  pushad
  xchg eax, esi ; esi=src
  mov edi, esi
  xor eax, eax ; we need to start with a nullbyte
  .Repeat
push eax
lodsb
  .Until !eax
  .Repeat
pop eax
stosb
  .Until !eax
  popad
  jmp edx
FlipFlopP endp

Weighs in at a whopping 23 bytes, and if you are not scared of using a lot of stack, it reverses about 100Mb/s :bg
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 27, 2011, 09:10:08 PM
That is brilliant, and your saying also speaks behind a lot of things if thought was in it  :U, but i was hoping to go a little bit more basic with a change of registry. I have been relaying on the old Irvine books,  :eek and I came across a register which I understand a little bit without thorough explaination. The EBP register is from, what I understand is a base pointer, but I hear its rarely refrenced that for some odd reason. So i took the piece in Strlen which should basically measure the lenghth of a String Entry, although there are easier means which I myself am sure of, I like to take things apart  :P. So, I did the following to test EBP and took out EAX:


Strlen  PROC
        PUSH    EBP
        MOV     EBP, ESP
        PUSH    EDI
        MOV     AL, 0
        MOV     EDI, EDX
        MOV     EDX, [EBP+8]
;        MOV     ECX, 0FFFFFFFFh
        REPNZ   SCASB
        NEG     ECX
        SUB     ECX,2
        POP     EDI
        POP     EBP
        RET

Now my question now is, I need to learn how to have a better handling with EBP. I suppose half idea programming is halfed the program.  :(

Quote from: dedndave on October 21, 2011, 02:47:49 AM
hiyas Jochen

i put a branch here originally to L2
;         Jmp L1   jump on itself makes no sense
it performs the "are we done" test for strings that have a length of 0 or 1
StrRev  PROC

;Call With: EDX = address of string
;           ECX = length of string
;
;  Returns: string is reversed

        PUSH    EAX
        PUSH    ECX
        PUSH    EDX
        DEC     ECX
        ADD     ECX, EDX
        JMP     L2

L1:     MOV     AL, [EDX]
        MOV     AH, [ECX]
        MOV     [ECX], AL
        MOV     [EDX], AH
        DEC     ECX
        INC     EDX

L2:     CMP     ECX, EDX
        JA      L1

        POP     EDX
        POP     ECX
        POP     EAX
        RET

StrRev  ENDP

Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 27, 2011, 10:17:26 PM
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
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 27, 2011, 11:09:05 PM
Thank you SOOOOOOOO Much, a better explaination of the fuctions of EBP & ESP and the like. One mistake I just learned from that thread is that in my pervious programs. I kept using ESP as a base pointer, as the thread explains, this is wrong lol. It explains a lot because I know now that when I did use ESP as a register, I had doubled my line work instead of keeping it short and simple, but many thanks now for that answered a lot of my questions.


Quote from: dedndave on October 27, 2011, 10:17:26 PM
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
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 27, 2011, 11:28:42 PM
well - you can use ESP to reference items on the stack, of course
and - sometimes we do - in order to avoid the stack frame overhead

however, it is tricky because every time you push or pop something, the offset of your variable relative to ESP changes
that is the main advantage of using EBP
the ESP pointer can go up and down with pops and pushes, but EBP stays the same   :U

there are some other more subtle differences
the intructions for using EBP to access stack variables have been optimized
for example, they are typically one byte smaller than the ESP equiv
on many CPU's, EBP can be a bit faster, as well
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 28, 2011, 12:37:42 AM
Excellent and I feel I am a bit closer to the understanding of EBP and ESP. Yet another question had arisen, and someone, mainly a friend asked me to do this same program I have done using a MACRO. Of course he wants me to do his homework and the twenty dollar fee is good enough. Problem is, the minute I sat down, wrote my outline, and am face to face with the screen and I notice I am uncertain with how to approach it. If there is anything i have been poorly taught WITHOUT THROUGH explaination, is MACROs. My understanding of Macro's is that they are supposed to be SMALL, and small titled, and a substitution of the vaulue will always occur, I.E

mPutChar MACRO char

   PUSH EAX (Somewhere in your MACRO you will use EAX.)
   MOV AL, char
   CALL WriteChar      
               
POP EAX
ENDM
               
mPutChar 'A' - The Code that will be substituted is:
PUSH EAX
MOV AL, 'A'
CALL WriteChar
POP EAX

Yet with this understanding that I have, how would approach it with the program at hand? I have an idea of it but I have to write the actual program first before I proceed. Perhaps any more expanded ideas for the community would be the most appreciative.

Quote from: dedndave on October 27, 2011, 11:28:42 PM
well - you can use ESP to reference items on the stack, of course
and - sometimes we do - in order to avoid the stack frame overhead

however, it is tricky because every time you push or pop something, the offset of your variable relative to ESP changes
that is the main advantage of using EBP
the ESP pointer can go up and down with pops and pushes, but EBP stays the same   :U

there are some other more subtle differences
the intructions for using EBP to access stack variables have been optimized
for example, they are typically one byte smaller than the ESP equiv
on many CPU's, EBP can be a bit faster, as well
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 28, 2011, 01:24:07 AM
that depends....
what percentage of that $20 were you planning on giving to me ?   :wink
i accept pay-pal   :bg

first, you have to have a need for a macro
this particular program may not have such a need

however, we can use a macro anyplace
here is what i suggest....

have a look at Kip's macro file (i think he named it macros.asm)
pick what is likely to be the simplest macro in there - "exit"
you will find that it is pretty easy to make a macro
then, pick one that has an argument and see how that is done
from what i remember about Kip's macros, they are all fairly simple

you can also read the documentation concerning macros in the MASM reference manual....
http://www.4shared.com/file/39MdNf_v/MASMProgGuide.html
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: StatusQuo on October 29, 2011, 06:31:06 PM
Dude you just opened my eyes, you deserve more than a $20 bucks friend. If it was in my power, I would give you a case of Wild Turkey and a hired Striper, that you never know was, and take you on that journey that Dr. Hunter S. Thompson took when he entered Fear and Loathing. Lol, Seriously dude you really gave me the insight i am looking for. Thanks a Million for my questions at an end.  :U I always loved this forum, strait talk, more learning, broader horizons, and hell of a good people.  :bg

Quote from: dedndave on October 28, 2011, 01:24:07 AM
that depends....
what percentage of that $20 were you planning on giving to me ?   :wink
i accept pay-pal   :bg

first, you have to have a need for a macro
this particular program may not have such a need

however, we can use a macro anyplace
here is what i suggest....

have a look at Kip's macro file (i think he named it macros.asm)
pick what is likely to be the simplest macro in there - "exit"
you will find that it is pretty easy to make a macro
then, pick one that has an argument and see how that is done
from what i remember about Kip's macros, they are all fairly simple

you can also read the documentation concerning macros in the MASM reference manual....
http://www.4shared.com/file/39MdNf_v/MASMProgGuide.html
Title: Re: Checking Backwards Capabillities Without Stacks.
Post by: dedndave on October 29, 2011, 07:15:12 PM
unfortunately, wifee would kill me if i got within a mile of a stripper   :lol