How to run a C binary from Assembly code?
I have this code in Assembly that I want to open a C program, passing a parameter and after the execution of this C program, a value is returned to my Assembly program.
More specifically, this:
- Open a C program passing a String as parameter.
- The C program will convert this String into a float and return it
- I'll catch this float and use it as I need in my assembly program.
[ASM] // Executing Assembly code \-------------> // Run C Program passing a value as parameter [C Program] // Do Stuff /-------------> // Return value that I can catch back in my Assembly code [ASM] // Goes back to 开发者_高级运维executing Assembly code using value the // value received by the C program.
Important info: I'm on Linux, and am not sure of what is my C binary. *.out maybe? Could use a few pointers on that too.
P.S: I'm aware of all the floating point instructions and the countless other options I have for doing that all in Assembly, but it's for my Computer Architecture and Organization class and that's how I need it to be.
Thanks everyone.
EDIT: Let me explain it a little better.
I have compiled this C code into a file called Convert and placed it into the same folder as my Assembly (.s) code:
//#includes
int main(int argc, char* argv[]){
float fVal;
sscanf(argv[1], "%f", &fVal);
return fVal;
}
Via Assembly, I want to execute Convert passing a string as "3.1415" as parameter. Convert will convert it to float and return.
Via Assembly, I'll then POP that from the stack and use the Float 3.1415.
All I have in mind is something like a System Call:
push parameter
push Executable's name
sys ! to wake the system to run my executable
pop eax ! pop the Float returned by Convert to EAX
Hope it's clearer now.
Again, thanks!
You can certainly achieve your overall goal of not having to write floating-point conversion code by hand in assembly by delegating to C instead, but you're thinking about the problem the wrong way. You don't need to call an entire C program from your assembly program, you just need to call one function. That one function is called strtod
, and you don't have to implement it, because it's already in the C library.
You appear to be on x86-32, so this should do what you want:
push $0x0 ; endptr
push parameter
call strtod
addl %esp, $8
; double return value is in %st(0)
If you are sure you want to execute the whole program and not just call a function, look into how to perform system calls (here's a link for Linux, though I haven't read this one), and then look at fork(2)
and wait(2)
. You will have to come up with a scheme to pass the result back, something like a pipe(2)
.
Edit 0:
You cannot return float
from main()
like that. First, it will be cast to integer, so you lose the fractional part. Second, only part of the word is actually used by the OS to return the program exit status. Check out the wait(2)
manual page for the macros you'd use in C to extract that status, and look into you libc headers to see what they do.
You need to use some other facility to return the floating point value from the process, maybe something like Unix pipeline.
This depends on the how the C Compiler generates the assembly/machine code, and what cpu it is running on.
Many 'C' compilers will pass the function arguments on the stack, which means you would have understand a stack frame, create one in the assembly code and then jump to your 'C' function/label.
So maybe the easy way to do this would be to create a Test 'C' application that calls your function, compile it and look at the assembly the compiler generates. Then use this assembly as example for how to call from your assembly code.
精彩评论