Home > Software engineering >  GNU Assembler GAS check if macro paramater is register
GNU Assembler GAS check if macro paramater is register

Time:07-13

I want handle in case if macro argument (parameter) is a register.

I expect I have similiar code like this but I'm sure it doesn't work due to lack my knowledge of directive syntax.

.macro myMacro myParameter
  .if \myParamater == "register"
    //a block code in case if paramater is register
    mov rax, 1
  .else
    //a block code in case if paramater is not register (maybe immadiately value)
    mov rax, 2
  .endif
.endm

So based on that code I can use macro like this

myMacro rdi //rax will be 1 because parameter is a register
myMacro 2 //rax will be 2 because parameter is not a register (immadiately value)

EDIT: So what is correct .if condition syntax to check if macro parameter is a register or not? Because I'm not sure in .if condition syntax.

CodePudding user response:

You maybe want check another else (not only register) for example check if it's a memory that store floating point or not.

First, you need define your own data type identifier.

You can set whatever number ID you want as long they are different each other.

// Define Identifier (ID) for your data type
.set REGISTER_TYPE_ID, 1
.set INTEGER_TYPE_ID, 2
.set FLOAT_TYPE_ID, 3
.set STRING_TYPE_ID, 4
.set FUNCTION_TYPE_ID, 5

Second, define every possible registers name with prefix TypeOf. to the REGISTER_TYPE_ID.

And again you can change prefix to whatever you want as long consistent to the macro.

// Define TypeOf for every possible registers in x64 machine
.set TypeOf.rax, REGISTER_TYPE_ID
.set TypeOf.rbx, REGISTER_TYPE_ID
.set TypeOf.rcx, REGISTER_TYPE_ID
// and so on...

Third, define your macro.

If you just want debug macro or assembler you don't have to use machine instruction like mov rax, 1, instead use .print "put string here"

.macro myMacro myParam
  .ifnotdef "TypeOf.\myParam"
    .print "This parameter type is an IMMEDIATELY value (constant)!"
  .elseif "TypeOf.\myParam" == REGISTER_TYPE_ID
    .print "This parameter type is a REGISTER!"
  .elseif "TypeOf.\myParam" == FLOAT_TYPE_ID
    .print "This parameter type is a FLOAT!"
  .else
    .print "Unknown type ID \myParam (elseif not implemented)"
  .endif
.endm

Example Usage

In this case there are another type to check for example float.

// Define Identifier (ID) for your data type
.set REGISTER_TYPE_ID, 1
.set INTEGER_TYPE_ID, 2
.set FLOAT_TYPE_ID, 3
.set STRING_TYPE_ID, 4
.set FUNCTION_TYPE_ID, 5

// Define TypeOf for every possible registers in x64 machine
.set TypeOf.rax, REGISTER_TYPE_ID
.set TypeOf.rbx, REGISTER_TYPE_ID
.set TypeOf.rcx, REGISTER_TYPE_ID
// and so on...

.macro myMacro myParam
  .ifnotdef "TypeOf.\myParam"
    .print "This parameter type is an IMMEDIATELY value (constant)!"
  .elseif "TypeOf.\myParam" == REGISTER_TYPE_ID
    .print "This parameter type is a REGISTER!"
  .elseif "TypeOf.\myParam" == FLOAT_TYPE_ID
    .print "This parameter type is a FLOAT!"
  .else
    .print "Unknown type ID \myParam (elseif not implemeted)"
  .endif
.endm

.data
  myVar: 
    .set TypeOf.myVar, FLOAT_TYPE_ID
    .float 1234

.text 
.global _start

myFunc:
  .set TypeOf.myFunc, FUNCTION_TYPE_ID
  mov rax, 123
  ret

_start:
  myMacro 453 //"This parameter type is an IMMEDIATELY value (constant)!"
  myMacro rax //"This parameter type is a REGISTER!"
  myMacro myVar //"This parameter type is a FLOAT!"
  myMacro myFunc "Unknown type ID myFunc (elseif not implemeted)"

_exit:
  mov rax, 60 //linux sys_exit
  mov rdi, 0
  syscall

OUTPUT:

wawan@LAPTOP-DJH6CVKH:~/asmi-fw$ as utama.s -o utama.o -msyntax=intel -mnaked-reg
This parameter type is an IMMEDIATELY value (constant)!
This parameter type is a REGISTER!
This parameter type is an FLOAT!
Unknown type ID myFunc (elseif not implemeted)
  • Related