News:

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

Checking Backwards Capabillities Without Stacks.

Started by StatusQuo, October 14, 2011, 12:59:23 AM

Previous topic - Next topic

StatusQuo

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

Then God sad, "In the beginning....There was SCOPE!", Then I asked, "What is Scope?", and God said...."A Stack Frame, geeze I forgot to include you with common sense, BUT a prototype you are, too wierd to live, to rare to die...", and it was written....

dedndave

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

StatusQuo

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.
Then God sad, "In the beginning....There was SCOPE!", Then I asked, "What is Scope?", and God said...."A Stack Frame, geeze I forgot to include you with common sense, BUT a prototype you are, too wierd to live, to rare to die...", and it was written....

StatusQuo

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
Then God sad, "In the beginning....There was SCOPE!", Then I asked, "What is Scope?", and God said...."A Stack Frame, geeze I forgot to include you with common sense, BUT a prototype you are, too wierd to live, to rare to die...", and it was written....

dedndave

well - i don't have Irvine32 set up
give me some time - i want to make a quicky masm32 equiv program

dedndave

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

dedndave

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:

StatusQuo

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
Then God sad, "In the beginning....There was SCOPE!", Then I asked, "What is Scope?", and God said...."A Stack Frame, geeze I forgot to include you with common sense, BUT a prototype you are, too wierd to live, to rare to die...", and it was written....

StatusQuo

And No Dave, I just copy and past my original worked program here, I get lazy dude, sorry  :lol
Then God sad, "In the beginning....There was SCOPE!", Then I asked, "What is Scope?", and God said...."A Stack Frame, geeze I forgot to include you with common sense, BUT a prototype you are, too wierd to live, to rare to die...", and it was written....

dedndave

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

dedndave

i just noticed the title of this thread   :bg

Gunner

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:
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

jj2007

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

dedndave

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

dedndave

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