In Visual Basic I can do this:
'
'
Dim FirstPart as String
Dim SecondPart As String
'
'
MsgBox FirstPart & SecondPart, vbOKOnly
'
'
How do you concatenate FirstPart and SecondPart in assembly?
What VB actually does is create a new temp buffer and uses the crt functions (or similar) lstrcpy (FirstPart) and lstrcat (SecondPart) to build the full string and then it passes the address of the temp buffer to the MsgBox function, and then free the memory.
...and it does it all with UNICODE strings, but I doubt that's much of a factor for your application.
Robert,
have a look in the MASM32 library, it has 2 seperate string concantenation procedures. There are macros that also use the procedures to make the technicue easier to use.
Quick and dirty.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\oleaut32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\oleaut32.lib
include \masm32\macros\macros.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
FirstPart db "FirstPart",0
SecondPart db "SecondPart",0
lpTemp dd 0
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
mov ebx, len( ADDR FirstPart ) ; MASM32 szLen
mov eax, len( ADDR SecondPart ) ; MASM32 szLen
add eax, ebx
mov lpTemp, alloc$( eax ) ; SysAllocStringByteLen
strcat lpTemp, ADDR FirstPart, ADDR SecondPart ; MASM32 szMultiCat
MsgBox 0, lpTemp, "Both Parts", MB_OK ; MessageBox
free$( lpTemp ) ; SysFreeString
exit ; ExitProcess
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Quote from: MichaelW on January 09, 2005, 08:21:51 AM
mov ebx, len( ADDR FirstPart ) ; MASM32 szLen
mov eax, len( ADDR SecondPart ) ; MASM32 szLen
add eax, ebx
mov lpTemp, alloc$( eax ) ; SysAllocStringByteLen
strcat lpTemp, ADDR FirstPart, ADDR SecondPart ; MASM32 szMultiCat
MsgBox 0, lpTemp, "Both Parts", MB_OK ; MessageBox
free$( lpTemp ) ; SysFreeString
exit
OK, that code works great. Thanks Michael.
Now if I make a function from that code. let's call it 'Concat' or whatever, is it possible to include that function as part of a paramater of another function call statement? Such as:
MsgBox 0, Concat(FirstPart, SecondPart), "Both Parts", MB_OK
How about a macro instead.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\oleaut32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\oleaut32.lib
include \masm32\macros\macros.asm
;--------------------------------------------------------------
; This macro allocates the necessary OLE string memory,
; copies a pointer to the allocated memory to a preexisting
; global DWORD named lpConcatBuffer, concatenates multiple
; strings into the allocated memory, and returns a pointer
; to the allocated memory.
;
; Any memory that was allocated by a previous call is freed
; before new memory is allocated, but the programmer is
; responsible for freeing the memory allocated by the last
; call.
;
; Note that lpConcatBuffer must be initialized to NULL.
;--------------------------------------------------------------
concat$ MACRO args:VARARG
push ebx
xor ebx, ebx
FOR var, <args>
mov eax, len( <var> ) ;; MASM32 szLen
add ebx, eax
ENDM
free$( lpConcatBuffer ) ;; SysFreeString
mov lpConcatBuffer, alloc$( ebx ) ;; SysAllocStringByteLen
FOR var, <args>
strcat lpConcatBuffer, var ;; MASM32 szMultiCat
ENDM
pop ebx
EXITM <lpConcatBuffer>
ENDM
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
FirstPart db "FirstPart",0
SecondPart db "SecondPart",0
lpConcatBuffer dd 0
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
MsgBox 0, concat$( ADDR FirstPart, ADDR SecondPart ), "Both Parts", MB_OK
MsgBox 0, concat$( SADD("junk,"), SADD(" junk,"), SADD(" and more junk") ),"Junk",MB_OK
free$( lpConcatBuffer ) ; SysFreeString
exit ; ExitProcess
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Michael,
That macro is excellent. Thank you so much. :clap: :dance: