I asked this in another forum but they don't seem to know. So I'm back here to ask the best. I'm wondering how I would write a byte to the middle of a string, IE so I can make a message box saying you have X items, where X is defined as a byte value.

Also is there a place with a source code to a text based game, it'll prolly reduce the number of questions I got.
Posted on 2003-06-11 23:41:14 by EEDOK
IIRC, there is a text based game wrote in HLA HERE - really cool stuff. ;)
Posted on 2003-06-11 23:51:20 by bitRAKE
k cool, can't find the thing to write a byte to the middle of a string in that program yet.. and the game I'm gonna make is gonna be a windows app :)
Posted on 2003-06-11 23:56:07 by EEDOK
To insert text in the middle of a string you're going to have to take your string apart.

You can use lstrcpyn to copy the specified number of characters and lstrcat to put everything together:

insert text into string at position 5

SourceString db "abcdefghijklmnop",0
InsertString db "12345",0
DestBuffer db 256 dup 0

invoke lstrcpyn,OFFSET DestBuffer, OFFSET SourceString, 5
invoke lstrcat, OFFSET DestBuffer, OFFSET InsertString

now you have to get the rest of the string, you do this by adding 6 to the base address of the string and using that as the pointer to the source string:

mov edx,OFFSET SourceString
add edx,6
invoke lstrcat, OFFSET DestBuffer, edx

The output should look like this:

adcde12345fghijklmnop
Posted on 2003-06-12 00:06:11 by donkey
Oh and if you just want to change a single byte in the middle of a string you can just mov it into the address of the byte:

mov edi,OFFSET String
mov ,BYTE PTR 'a'

This will replace the byte that is already in that position.
Posted on 2003-06-12 00:14:34 by donkey
off the top of my head.

I used this idea before when i wanted to plug numbers into a really big string
that I didn't want to cat to death.

First Spasm Syntax:



; Spasm Is wonderful
[push | push #1 | #+1]
[pop | pop #1 | #+1]
[call | push #L>2 | call #1]
[String: B$ 'You have played xxx number of games!' 0]
[SourceAsciiNumber: B$ '255' 0]
[SourceAsciiNumber1: B$ '13' 0]
Main:
mov esi SourceAsciiNumber
mov edi String
L1: inc edi | mov al B$edi | cmp al 0 | je L4> | cmp al 'x' | jne L1<
L2: mov al B$esi | cmp al 0 | jne L3> | inc esi | mov B$edi 020 | jmp L1<
L3: mov B$edi al | inc esi | jmp L1<
L4:

call 'USER32.MessageBoxA' 0 String String 0
call 'KERNEL32.ExitProcess' 0
ret


And the same thing in MASM32 Syntax:


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

.486
.model flat, stdcall
option casemap :none ; case sensitive

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

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

main PROTO

.data
String db "You have played xxx number of games!",0
SourceAsciiNumber db "255",0
SourceAsciiNumber2 db "13",0

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

.code

start:

call main

invoke ExitProcess,0

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

main proc

mov esi, OFFSET SourceAsciiNumber2
mov edi, OFFSET String
LP1: inc edi
mov al, BYTE PTR [edi]
cmp al, 0
je Done
cmp al, "x"
jne LP1
LP2: mov al, BYTE PTR [esi]
cmp al, 0
jne LP3
inc esi
mov BYTE PTR [edi], 020h
jmp LP1
LP3: mov BYTE PTR [edi], al
inc esi
jmp LP1
Done:

invoke MessageBox,0,OFFSET String, OFFSET String, 0
invoke ExitProcess,0

ret

main endp

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

end start


I know adding the spaces is a bit of a hack job, but this took me 3 minutes, longer to post it :)

RobotBob
Posted on 2003-06-12 00:24:01 by RobotBob
he posted at the nearly same time!
Are we sharing a brain? donkey lol
I should work faster

RobotBob
Posted on 2003-06-12 00:25:33 by RobotBob
:grin:

I think it's a Spasm/GoAsm thing RobotBob.

PS you really have to make your avatar transparent, it looks very cool.
Posted on 2003-06-12 00:29:42 by donkey
Psychic Friends? LOL :grin:

its transparent now.
Posted on 2003-06-12 00:31:32 by RobotBob
Actually RobotBob, you did that the hard way. Use this it's much better:

FmtString db "You have played %lu number of games!"

invoke wsprintf,lpbuffer,OFFSET FmtString, nGames

or if nGames is a string:

FmtString db "You have played %s number of games!"

invoke wsprintf,lpbuffer,OFFSET FmtString, OFFSET nGames

wsprintf is wonderful for that kind of thing.
Posted on 2003-06-12 00:50:52 by donkey
wsprintf is C style api.
After years of sprintf ing and printf ing such, I try and avoid them.
I also could call lstrcpy ,but why? rep movsb gives me the same.

They kinda take all the fun out of assembler :)

Lets build a better wsprintf!

Now thats an idea, I'll add that to my 'todo'.

RobotBob
Some Assembly Required
Posted on 2003-06-12 02:41:58 by RobotBob
RobotBob,

What's wrong with the Masm32 syntax? Many of us prefers it. :)

Instead of wsprintf, you can use some functions from the Masm32 lib which will
accomplish nearyl the same task.
Posted on 2003-06-12 03:13:06 by Vortex
I can't stand olives either and no matter what I say, Italy keeps shipping them GAH!

Everyone has different tastes, thank god there are choices.
Imagine using your 'state' issued assembler, oh my!

RobotBob Hates Olives!
Posted on 2003-06-12 03:17:34 by RobotBob
RobotBob,

Masm32 is not about olives.
Do you know that the oil extracted from olives is very good for the hearth?
Since I am citizen of a Mediterranean country,I wouldn't hate olives. :)

About different tastes,you are right.
Posted on 2003-06-12 03:26:58 by Vortex
printf() is a popular procedure in the C standard library, but ws/printf()'s string formatting scheme is entirely independent of the C language.
Posted on 2003-06-12 10:46:06 by iblis
why does this put weird characters at the end of the string?

.386

.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\ole32.inc
include \masm32\include\oleaut32.inc
include \masm32\include\shell32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\ole32.lib
includelib \masm32\lib\oleaut32.lib

popUp proto
.data
MBOX db "100 popups",0
String db "only %d popups to go",0
MyByte dd 064h

.data?
szBuff db 256 dup (?)


.code
start:
invoke popUp
invoke ExitProcess,NULL

popUp proc
mov eax,MyByte
.if eax >=1
invoke wsprintf, addr szBuff, addr String, eax
invoke MessageBox, NULL,addr szBuff, addr MBOX, MB_OK
sub MyByte,1
invoke popUp
.endif
ret
popUp endp

end start
Posted on 2003-06-12 23:26:42 by EEDOK
Works nicely for me. Win2K SP3
Posted on 2003-06-13 00:11:44 by donkey
WIN XP Service pack 1
Posted on 2003-06-13 00:40:10 by RobotBob
So no clue why it goes only ## pop ups to go? ? why is it putting the ? after? And just a side note it changes with whatever the byte value is..
Posted on 2003-06-13 08:52:07 by EEDOK
My guess would be the copy of code you are using does not end String with ",0". It might be hard to see if the comma "," is actually a semicolon ";". That would make the 0 part of a comment instead of code.
Posted on 2003-06-13 15:29:55 by tenkey