Author Topic: Option zerolocals  (Read 468 times)

JK

  • Regular Member
  • *
  • Posts: 48
Option zerolocals
« on: November 16, 2020, 03:05:24 AM »
"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:
Code: [Select]
...
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

  • Member
  • *****
  • Posts: 2506
Re: Option zerolocals
« Reply #1 on: November 16, 2020, 03:51:22 AM »
Hi JK,

Another test :

Code: [Select]
.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 :

Code: [Select]
_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

  • Member
  • *****
  • Posts: 11130
  • Assembler is fun ;-)
    • MasmBasic
Re: Option zerolocals
« Reply #2 on: November 16, 2020, 04:22:49 AM »
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.

Code: [Select]
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

  • Member
  • ****
  • Posts: 814
    • Uasm
Re: Option zerolocals
« Reply #3 on: December 05, 2020, 05:12:55 AM »
The option can be switched on/off at will. I will investigate why it doesn't work anymore.

jj2007

  • Member
  • *****
  • Posts: 11130
  • Assembler is fun ;-)
    • MasmBasic
Re: Option zerolocals
« Reply #4 on: December 05, 2020, 10:17:23 AM »
In case you don't find the bug: there are handy macros around :tongue:

Code: [Select]
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

  • Regular Member
  • *
  • Posts: 48
Re: Option zerolocals
« Reply #5 on: December 06, 2020, 04:20:54 AM »
Quote
I will investigate why it doesn't work anymore.

Thanks !

johnsa

  • Member
  • ****
  • Posts: 814
    • Uasm
Re: Option zerolocals
« Reply #6 on: February 26, 2021, 09:45:58 PM »
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.