I'm trying to convert an inline asm code form VS to GCC (AT&T).. the original code is this one:
char mystr[] = "Hello world";
_asm mov eax,0
_asm lea ebx, [mystr]
Here is my attempt to convert that code in gcc at&t syntax:
char mystr[] = "Hello world";
asm("mov $0,%%eax\n"
"leal (%0),%%ebx\n"
: : "r"(mystr));
This code doesn't seems to work, any idea why ?
Thank you very much
This code seems to works:
char* mystr = "Hello world";
asm("mov $0,%%eax\n"
"leal (%0),%%ebx"
::"b"(mystr));
I've changed char mystr[] to char* mystr, and "r" with "b"..
If somebody know what "b" does exactly, please let me know...
many thanks
Related
This question already has answers here:
How to set gcc or clang to use Intel syntax permanently for inline asm() statements?
(2 answers)
Can I use Intel syntax of x86 assembly with GCC?
(2 answers)
Closed last year.
I'd like to use intel syntax gcc inline assembly, leaving gcc's default -masm=att dialect untouched.
The following code works fine:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a = 123;
int b = 0;
printf("before: a = %d\n", a);
printf("before: b = %d\n", b);
__asm__ __volatile__ (
".intel_syntax noprefix\n\t"
"mov eax, %[a]\n\t"
"mov %[b], eax\n\t"
".att_syntax prefix\n\t"
: [b]"+r"(b)
: [a]"r"(a)
: "eax"
);
printf("after: a = %d\n", a);
printf("after: b = %d\n", b);
return 0;
}
// before: a = 123
// before: b = 0
// after: a = 123
// after: b = 123
But if i change Output Operands Constraint from register('r') to memory('m'), error occurs:
Error: junk `(%rbp)' after expression
In the generated assembly file, I find this:
#APP
.intel_syntax noprefix
mov eax, -16(%rbp)
mov -12(%rbp), eax
.att_syntax prefix
#NO_APP
It looks like gcc renders Assembler Template using AT&T Effective-Address dialect.
I searched the web, Extended Asm shows something like "Multiple assembler dialects in asm templates" and "x86 Operand Modifiers", but I still didn't solve the problem.
Is there a way to tell gcc, (maybe some instructions around __asm__, telling gcc to do operand-substitution with Intel-syntax addressing modes temporarily, like -masm=intel do in the whole file), render the Assembler Template using Intel Effective-Address dialect temporarily in __asm__ () block, not the whole file, like this:
#APP
.intel_syntax noprefix
mov eax, [%rbp - 16]
mov [%rbp - 12], eax
.att_syntax prefix
#NO_APP
I have been searching around for a while, and couldn't seem to find the answer to my issue. I'm trying to code some functions to detect whether or not the executable is being debugged, and I'm using some inline assembly for it (with the __asm tag). It keeps throwing two errors, and the rest of the code seems to compile fine. Here's the function
int peb_detect() {
__asm {
ASSUME FS : NOTHING
MOV EAX, DWORD PTR FS : [18]
MOV EAX, DBYTE PTR DS : [EAX + 30]
MOVZX EAX, BYTE PTR DS : [EAX + 2]
RET
}
}
and I keep getting the errors
warning C4405: 'FS': identifier is reserved word
warning C2400: inline assembler syntax error in 'opcode'; found 'FS'
warning C2408: illegal type on PTR operator in 'second operand'
I can't seem to figure it out. If anyone can help, I would really appreciate it. Thanks!
at first not 18 but 0x18 and not 30 but 0x30
C_ASSERT(FIELD_OFFSET(NT_TIB, Self) == 0x18);
C_ASSERT(FIELD_OFFSET(TEB, ProcessEnvironmentBlock) == 0x30);
need use not hard coded constants. especially wrong.
at second int peb_detect() must be __declspec(naked) if you use RET instruction. so code can look like this:
#include <winternl.h>
#include <intrin.h>
__declspec(naked) BOOLEAN peb_detect() {
__asm {
MOV EAX, FS:[NT_TIB.Self]
MOV EAX, [EAX + TEB.ProcessEnvironmentBlock]
MOV AL, [EAX + PEB.BeingDebugged]
RET
}
}
but we can use and shorter variant
__declspec(naked) BOOLEAN peb_detect2() {
__asm {
MOV EAX, FS:[TEB.ProcessEnvironmentBlock]
MOV AL, [EAX]PEB.BeingDebugged
RET
}
}
and for implement IsDebuggerPresent we can not use inline assembler at all. and this will be work for x64 too
__forceinline BOOLEAN peb_detect3()
{
return ((PEB*)
#ifdef _WIN64
__readgsqword
#else
__readfsdword
#endif
(FIELD_OFFSET(_TEB, ProcessEnvironmentBlock)))->BeingDebugged;
}
Here's what my screen looks like when I hit "Local Windows Debugger", then click the breakpoint button. The point it goes to is.....
http://i.stack.imgur.com/yufiH.png
My asm file says:
.model small
.stack
.data
.code
_Func proc
mov ax, 1
leave
ret
_Func endp
end
And the cpp file:
extern "C" {
int Func();
}
int main(int argc, char** argv) {
Func();
return 0;
}
So I'm wondering, why does this code hit this weird breakpoint. It isn't in my code...
And yes, I know what "int 3" in assembly means, that isn't what I'm wondering about. It isn't my code but it doesn't let my code run...
.model small is for 16-bit-MSDOS, not for 32-bit-Windows (Win32). Try following code:
.model flat
.code
_Func proc
mov eax, 1
ret
_Func endp
end
I am now trying to compile the following codes with gcc and codeblock:
#include <stdio.h>
int main()
{
char alphabet = 'X';
printf ("Type letter = ");
asm{ //line 8
mov ah, 02
mov dl, [alphabet] // line 9
int 21h
}
printf ("\n");
return (0);
}
The error messages I have got are as follows:
error: expected '(' before '{' token line 8
error: 'mov' was not declared in this scope line9
I am compiling for x86 computer, and was wondering how I could compile the above codes successfully. Thanks!
Unfortunately gcc doesn't support simple syntax like this:
asm {
mov ah, 02
mov dl, [alphabet]
int 21h
}
You can find more information on the gcc-inline-assembler with the link DCoder commented: click me
Explaining everything would be too much for an answer, so I simply write the code for gcc, which should do the job for you:
__asm__(
"movb $2, %%ah;"
"movb %0, %%dl;"
"int $0x21;"
:
: "r"(alphabet)
: "%ah", "%dl"
);
Note, that you can also use the keyword asm instead of __asm__.
for the sake of simplicity ill just paste an example instead of my entire code which is a bit huge. while im porting my code to VC++ instead of using GCC i need to rewrite a few inline assembly functions that receive pointers and save values on those pointers.
imagine cpuid for example:
void cpuid( int* peax, int* pebx, int* pecx, int* pedx, int what ){
__asm__ __volatile__( "cpuid" : "=a" (*peax), "=b" (*pebx), "=c" (*pecx), "=d" (*pedx) : "a" (what) );
}
that will just work, it will save the values on the registers "returned" by cpuid on the pointers that i passed to the function.
can the same be done with the inline assembler for VC?
so far the exact same function signature but with:
mov eax, what;
cpuid;
mov dword ptr [peax], eax;
etc
wont work, peax will have the same value it had before calling the function.
thanks in advance.
Tough to see because it is just a snippet, plus it could be called from C++ code / thiscall.
It might have to be 'naked' ( __declspec(naked) ) in some cases.
It won't port as VC is dropping x64 inline asm support iirc.
Use the __cpuid or __cpuidex intrinsic and enjoy.
mov eax, what;
cpuid;
mov ecx, dword ptr peax;
mov [ecx], eax;
will work.
Good luck!