News:

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

writing to strings?

Started by sixleafclover, January 20, 2006, 02:52:21 AM

Previous topic - Next topic

sixleafclover

Only read long story if you're bored, its the same question. Thanks for your time!! : :U

LONG story: Being fairly new to masm i wasnt sure if it could typecast (think thats the word) like C++, so got to work on a int > string converter (dword? int? is there a diff, isnt dword just limiting to FFFFFFFF?). Its all done and functional apart from that i'm not writing to string exactly how i'd like to. I'm using the write to buffer 2 method which means that i have no control over which string is getting outputted to, its always the same, whereas i'd like to use write to buffer 1 method (see code about this). What have i done wrong?

SHORT story: See code below.....why does writetobuffer not work properly??

NB: about both functions, in real use they also take an offset so i can write along the string instead of always first char, but i stripped that out to make the problem line more obvious.

CODE (excluding includes etc.):

writetobuffer proto stdcall : dword, :dword
writetobuffer2 proto stdcall : dword


.Data
mbTitle db "blah blah",0
buffer db 100 dup (?)

.Code
writetobuffer proc theBuffer:dword, theChar:dword
    mov eax, theChar
    mov dword ptr [theBuffer], eax
    ret
writetobuffer endp

writetobuffer2 proc theChar:dword
    mov eax, theChar
    mov dword ptr [buffer], eax
    ret
writetobuffer2 endp



Main:
;invoke writetobuffer, buffer, 48h ;<----- causes very odd messagebox
invoke writetobuffer, offset buffer, 48h  ;<------blank messagebox??
;invoke writetobuffer2, 48h ;<----- yay nice messagebox with an H (48h = "H") in it
invoke MessageBox, 0, addr buffer, addr mbTitle, 0

end_:


        Invoke    ExitProcess, 0
End Main                       

Mirno

You can't dereference memory.


writetobuffer proc theBuffer:dword, theChar:dword
    mov eax, theChar
    mov edx, theBuffer
    mov [edx], eax  ; DWORD PTR is not necessary as MASM can tell by the size of eax that it's a DWORD move.
    ret
writetobuffer endp


Note that you are moving four bytes into your string, in the example you are adding a "H", plus three null terminator characters...

Mirno



sixleafclover

oh, ok, thanks tis all fixed. :) what is dereferencing memory? and thanks for the reminder, i spose writing words would be better. just the byte i want and then a nice null. Out of interest, back to dwords for a minute, how could i write 2 bytes together? would i have to fit them both side by side in ax?

Mirno

When you have a pointer, you need to rerference what it is pointing to, but the x86 architecture does not allow you to do that dereference directly from a memory location. You must first move the pointer to a register, and de-reference from the register value.

If you are doing two bytes, it's better coding practice to use two byte moves as it's clear what is going on.

  mov al, character1
  mov [edx + 0], al
  mov al, character2
  mov [edx + 1], al

You can fit them in ax and do the move together, but you need to remember that they will be byte-swapped.
In terms of performance, unless the code is in some high performance loop (which is usually quite rare in string manipulation) it really won't make much of a difference.

Mirno

Ratch

sixleafclover,
     Here is the bottom line.  INTEL processors use little endian format.  That means when you read the memory contents into a multiple-byte register, the bytes become reversed.  They get reversed again when you write the multiple-byte register out to memory, so everything cancels out.  If you read the contents of another register into a multiple byte register, or a constant into a multiple byte register, the contents do NOT get reversed.  That means if you load up a multiple-byte register with a constant, and then write it out to memory, the value of that constant will have its bytes reversed in memory.  That is OK if the constant is a mulitple-byte binary representation of a number, because the CPU expects binary numbers to be reverse-byte in memory for arithmetic operations.  That is why MASM reverse-bytes the numbers it generates in the .DATA section.  The problem occurs when the "constant" is part of a multiple-byte ASCII representation of a string.  That part of the string will have its ASCII bytes reversed.  That problem becomes moot if you use single-byte registers for that operation, because they cannot reverse their single ASCII byte representation.  Or you can use the BSWAP instruction to reverse the bytes. Be happy, be very happy, that INTEL did not reverse the bits too.  Motorola products use the big endian format, so they don't have that problem.  Ratch