any way to insert real line breaks into a c macro?

  • Thread starter Thread starter Gabest
  • Start date Start date
G

Gabest

I'm asking this because I'd like to include a few (but often used) inline
assembly code via marcos to make the whole thing a bit more readable, and
more resistant to typos (by keeping the repeating code at one place only).
But I cannot because a macro cannot span to more lines and the assembler
just ignores the second, third, ... instructions in a row, even if I put
__asm before ever of them and separate with the ; character. A naked
function is not an option either, I need to set the register numbers with
the macro arguments, like xmm##src or xmm##dst.
 
Gabest,
I'm asking this because I'd like to include a few (but often used) inline
assembly code via marcos to make the whole thing a bit more readable, and
more resistant to typos (by keeping the repeating code at one place only).
But I cannot because a macro cannot span to more lines and the assembler
just ignores the second, third, ... instructions in a row, even if I put
__asm before ever of them and separate with the ; character. A naked
function is not an option either, I need to set the register numbers with
the macro arguments, like xmm##src or xmm##dst.

Use \:
 
Gabest,
I'm asking this because I'd like to include a few (but often used) inline
assembly code via marcos to make the whole thing a bit more readable, and
more resistant to typos (by keeping the repeating code at one place only).
But I cannot because a macro cannot span to more lines and the assembler
just ignores the second, third, ... instructions in a row, even if I put
__asm before ever of them and separate with the ; character. A naked
function is not an option either, I need to set the register numbers with
the macro arguments, like xmm##src or xmm##dst.

Use \:

#define ASMBLOCK(x,y) __asm { \

mov eax, y; \

mov x, eax; \

}
 
Use \:
#define ASMBLOCK(x,y) __asm { \

mov eax, y; \

mov x, eax; \

}

This is what I thought would work, but as I mentioned the assembler of vc71
_ignores_ the instructions after the first one when they are packed into one
line with the \ char. I think this is because everything after ; is a
comment in a raw asm file.

Btw, in this form above, it doesn't even compile, only if every line is
prepended with __asm.

The contents of asmtest.c:

#define ASMBLOCK(x,y) __asm { \
mov eax, y; \
mov x, eax; \
}

int _tmain(int argc, _TCHAR* argv[])
{
ASMBLOCK(esi, edi)
return 0;
}

After preprocessing:

asmtest.i:

int main(int argc, _TCHAR* argv[])
{
__asm { mov eax, edi; mov esi, eax; }
return 0;
}

After trying to compile it:

d:\Progs\asmtest\asmtest.cpp(15) : error C2400: inline assembler syntax
error in 'opcode'; found 'constant'
d:\Progs\asmtest\asmtest.cpp(18) : fatal error C1075: end of file found
before the left brace '{' at 'd:\Progs\asmtest\asmtest.cpp(12)' was matched

--

Now, with __asm everywhere:

#define ASMBLOCK(x,y) \
__asm mov eax, y; \
__asm mov x, eax; \

int _tmain(int argc, _TCHAR* argv[])
{
ASMBLOCK(esi, edi)
return 0;
}

asmtest.i:

int main(int argc, _TCHAR* argv[])
{
__asm mov eax, edi; __asm mov esi, eax;
return 0;
}

Assembly listing, asmtest.asm (as you can see, "mov esi, eax" is not there):

_main PROC NEAR ; COMDAT
; 11 : {
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
; 12 : ASMBLOCK(esi, edi)
mov eax, edi
; 13 :
; 14 : return 0;
xor eax, eax
; 15 : }
pop edi
pop esi
pop ebx
add esp, 192 ; 000000c0H
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
_main ENDP
 
Hi Ben,
don't use a semicolon:

indeed, I was just trying to make an example of the line splitting; didn't
care to compile it, and my asm days are far behind ;)
 
don't use a semicolon:

Normally I don't, I think it was just a last attempt to make it work.
http://msdn.microsoft.com/library/d...l/_core_defining___asm_blocks_as_c_macros.asp

"The third and fourth __asm keywords are needed as statement separators. The
only statement separators recognized in __asm blocks are the newline
character and __asm keyword. Because a block defined as a macro is one
logical line, you must separate each instruction with __asm."

Excellent, here is the answer to my question. Beside the newline char only
an additional __asm keyword could separates those lines. Thanks for pointing
me to this url, I havn't even thought there could be an article about this
problem already.
 
Back
Top