News:

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

Newbie question - buffer inside a procedure

Started by Marko, January 04, 2006, 04:16:56 PM

Previous topic - Next topic

Marko

Hi all,
i amnew here and i am trying to learn assembly and found this forum and that marvellous MASM32

i am doing some try this simple code covert from upper case to lower case


include \masm32\include\masm32rt.inc

   
    maiuscolo_a_minuscolo PROTO :DWORD, :DWORD
   
    .code

start:
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call main

    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

   
    .data
      string db "ABCDEFGHILMNOPQRSTUVZ",0
      string2 db 32 dup(0)
     
     
    .code
     
    print ADDR string,13,10
    invoke maiuscolo_a_minuscolo,ADDR string, LENGTHOF string
    print ADDR string2,13,10

    ret

main endp


maiuscolo_a_minuscolo proc lpStr:DWORD, lunghezza:DWORD

push esi
push edi
push ecx

mov esi, lpStr
mov edi, OFFSET string2
mov ecx, lunghezza
     
     again:
      lodsb
      or al, 100000b
      stosb
      loop again
     
pop ecx
pop edi
pop esi

ret

maiuscolo_a_minuscolo  endp

end start


Lets say that insted of use the OFFSET of string2 (or passing it byreference to the procedure) i i would like to create a buffer inside the procedure how can i achief that?

tnx in advance and sorry for the dumb question and my bad english

Marko

MichaelW

Hello Marko, welcome to the forum.

MASM32 includes two macros to automate this (CADD and SzText), but for clarity I coded it manually.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    call main
    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
    ; This jump directs the execution path around the data.
    jmp @F
    astring db "my other brother darryl",0
  @@: 
    print ADDR astring,13,10
    ret   
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

eschew obfuscation

Tedd

or, to answer your actual question...


maiuscolo_a_minuscolo proc lpStr:DWORD, lunghezza:DWORD
LOCAL buffer[128]:BYTE  ; <------ your new buffer

push esi
push edi
push ecx

mov esi, lpStr
lea edi,[buffer]    ;mov edi, OFFSET string2
mov ecx, lunghezza
     
     again:
      lodsb
      or al, 100000b
      stosb
      loop again
     
pop ecx
pop edi
pop esi
ret
maiuscolo_a_minuscolo  endp


This will create the buffer by moving the stack-pointer (esp) to give 128 bytes, each time you enter the procedure. And the buffer will be destroyed when you return from the procedure (when the esp is restored.)
[Remember that the buffer will not be zeroed (unless you do it), so it will first contain only junk.]
No snowflake in an avalanche feels responsible.

Marko

All right,

in the second exaple the buffer is created on the stack and obviosly it destroyed when the procedure return(as TEDD said) to the main program, in the fisrt example instead it s seems to me to is created like a static buffer (and it shold be not be destroyed when the procedure return). Now for example modifing my program and creating the buffer like in the fisrt manner so i could return to the main program the address of the buffer for future use ,when i compile i  get an error when the stosb instruction is executed it s say me Access violation.

So my question is,  when in C i declare a static variable in a procedure  so that is retained from calls how do i do this in assembly?

(my first idea to do this is to call inside the procedure a memalloc to create the buffer on the heap so it could accesible by evrywhere in the program)
tnx Marko

MichaelW


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    ; This makes the strings accessible outside the procedure.

    EXTERNDEF str1:BYTE,str2:BYTE

    call main

    print ADDR str1,13,10
    print ADDR str2,13,10

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc   

    ; This places the string data in the code segment. The jump
    ; is necessary to direct the execution path around the string
    ; data. The MASM32 szText macro can be used for this.

    jmp @F
    str1 db "str1",0   
  @@:

    ; This effectively places the string data in the data segment
    ; and then returns to the code segment. The MASM32 GLOBAL and
    ; STRING macros can be used for this.

    .data
      str2 db "str2",0
    .code

    print ADDR str1,13,10
    print ADDR str2,13,10

    ret

main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


If you need a general-purpose buffer then you should probably allocate memory, and define the handle and whatever else you need to use the buffer in the data segment outside of any procedure.



eschew obfuscation


Tedd

Quote from: Marko on January 05, 2006, 03:36:12 PM
when in C i declare a static variable in a procedure  so that is retained from calls how do i do this in assembly?
Together with the ".code" section, there are two other sections you should learn about.

.data        ;static variables - initialized (and usually with no need to be modified)
somestring  db "buongiorno!",0
someval     dd 46234259

.data?      ;non-initialized variables (a good place for global static buffers)
buffer   db 256 dup (?)


Look in other people's code for examples.

The variables in these sections are 'created' before the program starts, so there is no real create or destroy. And for anything very big then you should alloc the memory instead :wink
I would avoid putting variables/strings 'in' the code (where you have to jump past them), especially if they are going to change.
No snowflake in an avalanche feels responsible.

Marko

perhaps actually i still think a little bit with a C mind, i need pratice.

Tedd

C isn't too far from asm, but it does cover a few details.

When you create a static variable (inside a procedure, or as a global) it will usually be 'created' in the .data? section.
The only difference with it being inside the procedure is that you can't reference that label outside of the procedure. But the variable still exists outside of the procedure and will exist even if you never use the procedure (unless the compiler is clever.)
No snowflake in an avalanche feels responsible.