Author Topic: [Feature Suggestion] allow some higher level args and local vars management  (Read 9842 times)

Offline ben321

  • Full Member
  • **
  • Posts: 182
First, allow a line like this in NASM code.
"Function MyFunc arg1,word arg2,dword arg3,arg4"
Notice this line has 3 separate sections (each separated by a space). It starts with the keyword "Function", followed by the name of the function, followed by an argument list (each argument name is separated by a comma, and each argument could also have a size override keyword like "word" or "dword"). It also would be valid to have no argument list, if your function didn't have any arguments.
When the Function keyword is used, this would perform several different things.
First it would declare the label MyFunc, just as if I had used "MyFunc:".
Second, it would automatically insert "PUSH EBP" and "MOV EBP,ESP".
Third, it would define arg1, arg2, etc as pointing to the correct location on the stack for each of these function args (for example, arg1 would be defined as "EBP+8", so they could be used later instead of directly referring to EBP plus some offset (this takes the burden off the programmer for remembering which function arg was stored where in the stack).
Fourth. It would also start a function managing mode that would allow handling of local variables in a similar way, and this mode would be closed by an EndF statement.
The size of each argument would be assumed to be 4bytes in 32bit mode and 2bytes in 16bit mode, unless overridden with a size keyword like "word" or "dword".

Next thing that I would like to see added to NASM, and related to the first of these things, is management for local variables. It would work like this.
"Locals var1,word var2, dword var3,var4"
Notice this line has 2 separate sections (each separated by a space). It starts with the keyword "Locals", followed by a variable list (each variable name is separated by a comma, and each variable could also have a size override keyword like "word" or "dword").
When the Locals keyword is used, this would perform several different things.
First it would allocate space on the stack for the variables with a SUB instruction.
Second, it would define var1, var2, etc as pointing to the correct location on the stack for each of these local vars (for example, var1 would be defined as "EBP-4", so they could be used later instead of directly referring to EBP minus some offset (this takes the burden off the programmer for remembering which local variable was stored where in the stack).
The size of each variable would be assumed to be 4bytes in 32bit mode and 2bytes in 16bit mode, unless overridden with a size keyword like "word" or "dword".

The last thing that would be required for a function section would be a way to close the function management mode at the end of the function. This would be a accomplished with an EndF keyword.
That keyword would would just be used by itself, without any other text after it. It would do several things.
First it would deallocate any space on the stack for local variables (using an ADD instruction), if any local vars had been allocated previously with the Locals keyword.
Second, it would remove any definitions for the local variables names.
Third, it would remove any definitions for the function argument names.
Fourth, it would use either a LEAVE instruction, or a combination of "MOV ESP,EBP" and "POP EBP" instructions, to end the function frame.
A RET instruction, or RET ArgCount instruction would still need to be typed by the programmer after the use of the EndF keyword, to actually return from the function.


And one other suggestion, this time on the end of the calling function, rather than the called function. And that is the addition of an Invoke keyword.
This is similar to the CALL instruction, except it removes the need for several separate PUSH instructions for pushing args onto the stack for the function being called. It would be a single line of code, instead of several lines of code, and would look like this.
Invoke MyFunc arg1,arg2,arg3,arg4
It contains 3 space-separated sections. These are the Invoke keyword, the function name, and a comma-separated argument list.
An argument could be anything that would be allowed in a PUSH instruction. For example:
Invoke MyFunc EAX,dword[EBP],MyVar,word[MyVar2],byte[MyVar3],DX