News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Option zerolocals

Started by JK, November 16, 2020, 03:05:24 AM

Previous topic - Next topic

JK

"option zerolocals : 1" should (at least to my understanding) initialize all locals of a procedure to zero, but it doesn´t

32 bit code for UASM:

...
include windows.inc
includelib kernel32.lib
includelib user32.lib

option ZEROLOCALS : 1


.data
MsgCaption      db "Test",0
MsgBoxText      db "works",0


.code
start proc
;***************************************************************************
;
;***************************************************************************
local n       :dword
LOCAL rct     :RECT                                   ;is created on the stack


int 3
  mov eax, rct.left
  mov rct.left,   1
;int 3                                                 ;at this point i would expect EAX to be zero
  mov eax, rct.left
  mov ebx, n                                          ;at this point EAX = 1, which is expected


  invoke MessageBox, NULL, addr MsgBoxText, addr MsgCaption, MB_OK
  invoke ExitProcess, NULL
  ret

start endp


end start


;*************************************************************************************
; code generated
;*************************************************************************************
;00081000 <Mod>  55                PUSH    EBP
;00081001        8BEC              MOV     EBP, ESP
;00081003        83C4 EC           ADD     ESP, -14
;00081006        CC                INT3
;00081007        8B45 EC           MOV     EAX, DWORD PTR SS:[EBP-14]
;0008100A        C745 EC 01000000  MOV     DWORD PTR SS:[EBP-14], 1
;00081011        8B45 EC           MOV     EAX, DWORD PTR SS:[EBP-14]
;00081014        8B5D FC           MOV     EBX, DWORD PTR SS:[EBP-4]
;00081017        6A 00             PUSH    0
;00081019        68 00300800       PUSH    Sample2.00083000                               ; ASCII "Test"
;0008101E        68 05300800       PUSH    Sample2.00083005                               ; ASCII "works"
;00081023        6A 00             PUSH    0
;00081025        FF15 08200800     CALL    DWORD PTR DS:[<&USER32.MessageBoxA>]           ; USER32.MessageBoxA
;0008102B        6A 00             PUSH    0
;0008102D        FF15 00200800     CALL    DWORD PTR DS:[<&KERNEL32.ExitProcess>]         ; kernel32.ExitProcess
;00081033        8BE5              MOV     ESP, EBP
;00081035        5D                POP     EBP
;00081036        C3                RETN



The generated code doesn´t change regardless of the actual setting of "option zerolocals" (0 or 1), stepping through the code shows, that (in my case) rect.left is 0x48 (not zero). The reserved stack space for locals isn´t cleared (set to zero).

What am i doing wrong?


Thanks


JK

Vortex

Hi JK,

Another test :

.386
.model flat,stdcall
option casemap:none
option ZEROLOCALS:1

ExitProcess PROTO :DWORD
printf      PROTO C :VARARG

.data

string1     db '%u %u',0


.code

start:

    call    main
    invoke  ExitProcess,0

main PROC

LOCAL x:DWORD
LOCAL y:DWORD

    invoke  printf,ADDR string1,\
            x,y
    ret

main ENDP

END start


Disassembling the object module :

_start  PROC NEAR
        call    _main@0
        push    0
        call    _ExitProcess@4

_main@0 LABEL NEAR
        push    ebp
        mov     ebp, esp
        add     esp, -8
        push    dword ptr [ebp-8H]
        push    dword ptr [ebp-4H]
        push    offset _string1
        call    _printf
        add     esp, 12
        leave
        ret
_start  ENDP


The two locals x and y are not set to 0.

Tested with UASM v2.49, Jun 21 2019

jj2007

Can the option be switched on and off repeatedly? For performance reasons, I don't think it's a good idea to clear all local variables throughout a whole program. For example, in my editor's source I use ClearLocals only in 45 of 200 procedures.

MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT, TheString
  LOCAL v1, v2, rc:RECT, buffer[100]:BYTE ; ordinary locals first
_Local v3=123, v4:REAL4=123.456 ; see SetFloat for allowed syntax
_Local x$="Hello World", y$=TheString ; strings can be initialised, too
  ClearLocals ; first line after the LOCALs
  MsgBox 0, Str$("The value of v1: %i", v1), "Test clv:", MB_OK
  ret
MyTest endp

johnsa

The option can be switched on/off at will. I will investigate why it doesn't work anymore.

jj2007

In case you don't find the bug: there are handy macros around :tongue:

MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT, TheString
  LOCAL v1, v2, rc:RECT, buffer[100]:BYTE ; ordinary locals first
  _Local v3=123, v4:REAL4=123.456
  _Local x$="Hello World", y$=TheString ; strings can be initialised, too
  ClearLocals ; first line after the LOCALs
  MsgBox 0, Str$("The value of v1: %i", v1), "Test clv:", MB_OK
  ret
MyTest endp

JK

QuoteI will investigate why it doesn't work anymore.

Thanks !

johnsa

The option is only available in 64bit code. 32bit doesn't warn that it will have no affect. For 32bit code I'd use the macros. I will update UASM to warn that it has no effect in 32bit mode.