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
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
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.
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
well - i don't have Irvine32 set up
give me some time - i want to make a quicky masm32 equiv program
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
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:
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
And No Dave, I just copy and past my original worked program here, I get lazy dude, sorry :lol
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
i just noticed the title of this thread :bg
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:
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
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
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
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
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
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
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
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
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
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
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
unfortunately, wifee would kill me if i got within a mile of a stripper :lol