News:

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

Main Menu

How to re-define a variable in code

Started by Jbarrera, March 11, 2018, 01:15:15 PM

Previous topic - Next topic

Jbarrera

Hello,
I'm trying to figure out how it is possible to re-define a variable in the code. I could have sworn someone said it could be done.

So for example lets say I have the following piece of code



.data
    myVariable  = 10
.code
main PROC

;some code and calculations
;can I do the following?

mov   eax, myVariable
add    eax,5

mov   myVariable,eax   ;can I update the new value of my variable?



end

main END



So when using the = operator or the EQU operator, can any of the variable be changed further down the code? or would I have to do something like:
myVariable   dword     10

Thank you

Mikl__

#1
Hi, Jbarrera!
if you wrote myFirstVariable  = 10
mysecondVariable  equ 10
Your myFirstVariable and mySecondVariable are not variables, but they are constants. You must define constant in any section. If you need variables myFirstVariable  and mySecondVariable you must write in section .data or .data?myFirstVariable  dd 10
mySecondVariable dd ?
Variable1 db 23
Variable2 byte 24h
variable3 sbyte -35
variable4 dw 123h
variable5 word ?
variable6 dq 4FFFFFFFFFh
The intrinsic types for MASM are:

|size in bytes|bits|Directive |Description of Initializers
|BYTE=1|8 |db (=define byte), byte,|Allocates unsigned numbers from 0 to 255
|||sbyte (sign byte)|Allocates signed numbers from –128 to +127
|WORD=2|16|dw (=define word), word,|Allocates unsigned numbers from 0 to 65,535 (64K)
|||sword (sign word)|Allocates signed numbers from –32,768 to +32,767
|doubleword=4|32|dd (=define doubleword), dword,|Allocates unsigned numbers from 0 to 4,294,967,295 (4G)
|||sdword (sign doubleword),|Allocates signed numbers from –2,147,483,648 to +2,147,483,647
|||real4|1.18 x 10-38 to 3.40 x 1038
|farword=6|48|df (=define farword), dp, fword|Allocates 6-byte integers. These values are normally used only as pointer variables on the 80386/486 processors
||||Allocates unsigned numbers from 0 to 281,474,976,710,655 (256T)
||||Allocates signed numbers from –140,737,488,355,328 to +140,737,488,355,327
|qwadword=8|64|dq (=define quadword), qword|Allocates 8-byte integers used with 8087-family coprocessor instructions 0 to 18,446,744,073,709,551,615 (16E)
|||sqword (sign qwadword),|Allocates signed numbers from -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807
|||real8|2.23 x 10-308 to 1.79 x 10308
|10 bytes|80|dt (=define ten bytes), tbyte|Allocates 10-byte integers if the initializer has a radix specifying the base of the number
|||real10|3.37 x 10-4932 to 1.18 x 104932 real numbers or BCD-numbers
|octoword=16|128|oword (=define octoword)|Allocates unsigned numbers from 0 to 3.4028236692093846346337460743177 x 1038

jimg

Yes, you can change assembly time variables.  That's basically what the   '='  notation is for.  But you have to be aware that the addition does not happen during execution, it happens only during assembly.  Any change to the variable affects only code that follows the change, and not any code that precedes the change, no matter how you jump around during execution.

myvariable = 5
.
testloop:
. ; for these instructions, myvariable always equals 5
.
myvariable = myvariable+5   ; for any following instructions, myvariable is now equal to 10.
.
. ; for these instuctions, myvariable always equals 10
.
jmp testloop  ; even though you jump back, the value of myvariable will not change.

aw27

Actually "variables" are the register contents everything else, namely EQU, TEXTEQU and =, are preprocessor directives or macro equivalents.

Some assembly languages, like the AVR assembly language, that some people here may know about (particularly Arduino lovers), even consider good practice to replace the register names with variable names and these names can even be redefined later. Example:

; Define variable names for some registers
.def sum = r25
.def var1 = r16
.def var2 = r17

ldi sum, 0
ldi var1, 1
ldi var2, 2
add sum, var1
add sum, var2

end:
rjmp end

; undefine them so that the registers can receive new names if needed
.undef var1
.undef var2
.undef sum


daydreamer

Quote from: aw27 on March 11, 2018, 06:46:12 PM
Actually "variables" are the register contents everything else, namely EQU, TEXTEQU and =, are preprocessor directives or macro equivalents.

Some assembly languages, like the AVR assembly language, that some people here may know about (particularly Arduino lovers), even consider good practice to replace the register names with variable names and these names can even be redefined later. Example:

; Define variable names for some registers
.def sum = r25
.def var1 = r16
.def var2 = r17

ldi sum, 0
ldi var1, 1
ldi var2, 2
add sum, var1
add sum, var2

end:
rjmp end

; undefine them so that the registers can receive new names if needed
.undef var1
.undef var2
.undef sum
you can redefine real4 to float,you can redefine even keywords like MMX mmenmonics to be SSE2 mnemonics, so it might be possible to redefine registers to be variable names in masm32, isnt those also treated as keywords?

my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

Quote from: daydreamer on March 11, 2018, 11:32:45 PMit might be possible to redefine registers to be variable names in masm32

The other way round; you cannot call a memory variable "eax", unless you use a special directive, see OPTION below. But equates are indeed powerful, simple example:
.data ; initialised data section
MyWinStyle = CS_HREDRAW or CS_VREDRAW or CS_OWNDC ; see pros and cons of CS_OWNDC
wcx WNDCLASSEX <WNDCLASSEX, MyWinStyle, WndProc, 0, 0, 1, 2, 3, COLOR_BTNFACE+1, 0, txClass, 4>
...
  wc equ [edi.WNDCLASSEX] ; we use an equate for better readability
  mov edi, offset wcx
  mov wc.hInstance, rv(GetModuleHandle, 0) ; rv ("return value") is a Masm32 macro
  mov wc.hIcon, rv(LoadIcon, eax, IDI_APPLICATION) ; OPT_Icon Smiley    ; see \Masm32\MasmBasic\icons
  mov wc.hIconSm, eax ; the rv macro returns results in eax
  mov wc.hCursor, rv(LoadCursor, NULL, IDC_ARROW) ; get a cursor
  invoke RegisterClassEx, addr wc ; the window class needs to be registered


Regarding constants, there is one important rule for Masm: number equates cannot be used twice.
include \masm32\include\masm32rt.inc

option nokeyword:<eax>

number=1 ; a numeric constant
number=2 ; no problem

num2 equ 1 ; a numeric equate
; num2 equ 2 ; Error A2143: Symbol redefinition: num2

num3 equ <1>
num3 equ <2> ; no problem because <1> is a string
num3 equ <chr$("hello world", 13, 10)> ; no problem


.data
eax dd 123, 0

.code
start:
  print num3
  inkey str$(eax), " is the number"
  mov eax, 12345 ; OK
  ; mov eax, eax ; Error A2049: Invalid instruction operands
  exit

end start


The three definitions look very similar, but they aren't:
number is a constant assigned with = and can be redefined;
num2 is a numeric equate, it cannot be redefined;
num3 is a string equate, it works exactly like a numeric one but can be redefined.

aw27

Quote
you can redefine real4 to float,you can redefine even keywords like MMX mmenmonics to be SSE2 mnemonics, so it might be possible to redefine registers to be variable names in masm32, isnt those also treated as keywords?

Nope, but in JWASM or later variations you can.


.386
.model flat, stdcall

OPTION RENAMEKEYWORD:<eax>=total
OPTION RENAMEKEYWORD:<ebx>=value1
OPTION RENAMEKEYWORD:<ecx>=value2

.code

start proc
mov total, 0
mov value1, 1
mov value2, 2
add total, value1
add total, value2
ret
start endp

end



It can also be renamed multiple times.

aw27

Some fun is also available in MASM with textequ, though:


.386
.model flat, stdcall

total textequ <eax>
value1 textequ <ebx>
value2 textequ <ecx>

.code

start proc
mov total, 0
mov value1, 1
mov value2, 2
add total, value1
value2 textequ <edx> ; Can be redefined
add total, value2
ret
start endp

end

jj2007

Quote from: aw27 on March 12, 2018, 12:42:31 AM
Quote
you can redefine real4 to float,you can redefine even keywords like MMX mmenmonics to be SSE2 mnemonics, so it might be possible to redefine registers to be variable names in masm32, isnt those also treated as keywords?

Nope, but in JWASM or later variations you can.

My example above with option nokeyword:<eax> builds fine with Masm version 6.14 ... 14.0

Quote from: jj2007 on March 12, 2018, 12:15:03 AM

option nokeyword:<eax>
...
.data
eax   dd 123, 0
...
  mov eax, 12345   ; OK
  ; mov eax, eax      ; Error A2049: Invalid instruction operands

RuiLoureiro

Hi Jbarrera
Quote from: Jbarrera on March 11, 2018, 01:15:15 PM
Hello,
I'm trying to figure out how it is possible to re-define a variable in the code. I could have sworn someone said it could be done.

So for example lets say I have the following piece of code
    myConstant  = 5 
.data
    ;myVariable  = 10     ; this is a constant 10  in the asm text ««« see all help above

      myVariable dd 10  ; «««« this is a dword in memory that starts with 10

.code
main PROC

;some code and calculations
;can I do the following?           ««««« YES !

mov   eax, myVariable     ;«««« here we move the dword myVariable to EAX (dword also)
add    eax,5                    ; «««« here we add 5
; add eax, myConstant    ; «««« is the same as add eax, 5

mov   myVariable,eax   ;can I update the new value of my variable?
                                  ; YES we can, but see the definition in .data section
end

main END

So when using the = operator or the EQU operator, can any of the variable be changed further down the code? or would I have to do something like:
myVariable   dword     10

Thank you
Olá Mikl__  :t
Hi Jochen    :t

Jbarrera

Thank you everyone for the input and clarification. Ok so this makes sense very good explanation