There are three basic types of operands that can be placed in a register: immediate, memory or another register.
An immediate operand is usually a numeric literal (number) but it can also be a string literal in the form "a" which is converted by PowerBASIC to its ASCII equivalent code.
! MOV AL, "a" ; String literal
! MOV EDX, 0 ; Numeric immediate/literal
A memory operand is an address in memory of some form of data:
! MOV AL, [ESI] ; Copy byte at address in ESI into AL
! MOV EDX, lpMemvar ; Copy variable address into EDX
A register operand is a register with a value in it:
! MOV ECX, EDX ; Copy EDX into ECX
The actions that can be performed are determined by the available opcodes. For example, trying to move one memory operand directly into another does not work because there is no opcode in the 80x86 processor to do it.
! MOV mVar, lpMem ; This fails as there is no opcode
However, if you have a "spare" register, you make an indirect copy through that register:
! MOV EAX, lpMem ; Copy memory value into register
! MOV mVar, EAX ; Copy register into memory variable
If you don't have a "spare" register, it can be done another way but it is slightly slower:
! PUSH lpMem ; Push memory value onto the stack
! POP mVar ; Pop it off as another memory value
The Inline Assembler
Saving Registers at the Sub/Function level
Using ESP and EBP
Saving the FPU registers