This experiment is on the 32 bit Linux.
I want to do a transformation on the asm level, and I am trying to implement
my transformation before the function main is called.
Currently I am trying to program a new entry point, implement my transformation code,
and hope this new entry point can successfully call main
Basically the default entry point of gcc generated assembly code is main, which I give an example as follow:
c code:
int main()
{
return 0;
}
I use this command to generate asm code:
gcc -masm=intel -fno-asynchronous-unwind-tables -S main.c
and this is what I got:
.file "main.c"
.intel_syntax noprefix
.text
.globl main
.type main, #function
main:
push ebp
mov ebp, esp
mov eax, 0
pop ebp
ret
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",#progbits
Could anyone tell me how to implement a new entry point(probably a function similiar like _start) and call main at the end of this new entry point?
Thank you!
I doubt you should replace _start() because it's very platform- and libc-specific. Either you write all code in assembler and so you don't need libc-specific initialization, or you should copy all _start() activity including things you aren't aware. The latter looks simply bogus.
If you agree not to replace start() but use a mechanism to run some code before main(), declare a function with __attribute__((constructor)). This is documented GCC extension and it's actively used e.g. for static object initializing in C++. Such function can't get arguments or return a real value, nor shall it override control flow in another way. I can't catch what you mean for "transformation" so it can contradict to your intention; if so, you would have explained this more detailedly.
Related
Questions are:
What is the difference between .section .text and .text, in assembly code, when using gcc.
And, what does .ascii mean in .ascii "Hello, world\n"?
.text says the next code is to go into the text segment.
section .text is to create a new, unnamed, section under ".text" to put the next code in.
A section is a minimal unit of instructions belonging together (usually a function/symbol) for the purpose of dead code elimination.
for example in entry.S
ENTRY(ret_from_fork)
pushl %eax
call schedule_tail
GET_THREAD_INFO(%ebp)
popl %eax
jmp syscall_exit
so what's the syntax of ENTRY in as language?
I think all the directive of as is start with . and the ENTRY also doesn't look like a macro
can anyone tell me about the ENTRY is what? if it is defined in Linux source code could anyone indicate the location or if it is a syntax in as can someone tell me where i can find the specific description of this use!
Thanks!
Not sure why you say it doesn't look like a macro, because that's exactly how macros look like. And indeed it is a macro defined in include/linux/linkage.h as follows:
#ifndef ENTRY
#define ENTRY(name) \
.globl name ASM_NL \
ALIGN ASM_NL \
name:
#endif
I think that's an assembler directive .
As per my knowledge ENTRY assembler directive is used when we use Keil assembler.
That's actually the entry point of a application.
The way we have _start or _main entry point in assembly code when we use GNU assembler.
I want to call define a function in asm file and call this function from a Cpp file/function. Also I have to compile the project on 64-bit platform.
Please help me in doing that as I don't have much idea about assembly code. Any help will be appreciated.
Thanks
This file is an ASM file from ffdshow that performs some work with CPUID. It's both x64 and x86. YASM is used to assemble it.
What most people do today is not write ASM code but use intrinsic functions. There are intrinsic functions for all SSE/AVX/etc. even for low level ring0 instructions. Intrinsic functions allow the compiler to do extra optimizations and are shared between 32 and 64bit builds.
A code snippet would help, but if you want to place inline assembly within a regular C++ function, you can do that by placing it in an asm block like this:
void myClass::myFunc() {
// cpp code
int a = 0;
// ...
// asm code
__asm {
mov eax, ebx;
// ...
};
// more cpp code
// ...
}
I'm trying to port a program to x64 using vs2008. The problem is, however, that the is some inline asm code that is not supported on x64. This asm code is used to push arguments with unknown type or number to functions from dll. It is an interpeter based program in which you can specify a function to use from a certain dll and the program pushes the arguments and calles the function at compile time.
Using various sources I've concluded that generating seperate .asm files that contain asm functions which can be compiled unsing masm and their obj files linked to vs2008. Using different files for x86 and x64 the program builds for both problems. The problem is however, that the functions do not replicate what the inline asm is doing.
I converted the following inline code, for example:
double a = Evaluate(arg[i]).num;
_asm push a + 4
_asm push a
j += 8;
To:
double a = Evaluate(arg[i]).num;
EvaluateFuncArgFloat(a);
j += 8;
With the follwoing .asm file:
TITLE EvaluateFuncArgFloat (evaluate_asm.asm)
.386
.model flat, C
.code
EvaluateFuncArgFloat PROC a:DWORD
push a + 4
push a
ret
EvaluateFuncArgFloat ENDP
END
This does not do what I'm expecting. The double simply does not end up in the function as it did when using inline asm.
My guess is that there is a small error or something I've left out, but after many tries I can't seem to get it to work. Hopefully someone can help me with this problem, it is very much appriciated.
A sneaky way to do this could be
EvaluateFuncArgFloat PROC a:DWORD
pop eax ;ret address popped to a safe register (if not ax/eax)
push a + 4
push a
push eax ;ret address back at top of stack
ret
EvaluateFuncArgFloat ENDP
The problem is you've pushed 2 numbers onto the stack and not removed them a+4 and a
Presumably another part of your original code deals with this in the original program
I need to put markers to C++ code that should be visible in assembly or binary. It seems it’s straight forward to do it for 32 using inline assembly:
__asm {
NOP
NOP
NOP
}
or using DB assembly statement:
__asm {
DB 0x00, 0xFF, 0x10
}
But VisualStudio 2005 and better does not support inline assembly for x64. Is there any way to do it? Probably I can make a function in separate assembly module but how I can be sure that linker will put an actual assembly there instead of CALL?
Define a global volatile variable somewhere, say volatile __int64 blah = 0;. Then wherever you want some marker, use _InterlockedCompareExchange64(&blah, SOME_UNIQUE_CONSTANT1, SOME_UNIQUE_CONSTANT2);. You'll be guaranteed to find instructions loading ECX:EBX with SOME_UNIQUE_CONSTANT1 and EDX:EAX with SOME_UNIQUE_CONSTANT2 followed by LOCK CMPXCHG8B (0xF0, 0x0F, 0xC7, etc -- see instruction encoding details).
The MSDN says you can use intrinsic functions.
//MyAsmCode.asm
.code
MyFunction proc
...
MyFunction endp
end
compile it (ml64.exe).
You get object file (MS COFF 64): MyAsmCode.obj
In VS add MyAsmCode.obj to linker additional dep.
Now you can call this function. ;)