guest54
Guest
|
|
« on: December 20, 2011, 12:35:14 pm » |
|
By way of supplement I would like to give a little detail about a very strange phenomenon indeed.
First consider this "c" programme - it is about the simplest "c" programme imaginable; it adds 1 to 2 and obtains the result 3:
------------------------------------------------------------------------------- /* An extremely simple "c" programme */ int main( void ) { int numa, numb, numc; numa = 1; numb = 2; numc = numa + numb; printf( "The answer is %lld\n", numc ); } ----------------------------------------- k: cd \"Microsoft Visual Studio 10.0"\VC call vcvarsall.bat x64 e: cl Simplec.c pause --------------------------------------------------------------------------------
After compilation the resultant executable file simplec.exe occupies 51,712 bytes on my hard drive (which of course will be rounded up to the next highest allocation unit, and becomes 53,248 bytes on my machine).
Secondly, now, consider this assembly language programme, which calls a "c" function. Again the "c" function adds 1 to 2 and obtains the result 3. The only real difference between this function and the main programme above is that this is called from a main programme written in assembly language:
--------------------------------------------------------------------------------
; Example of calling a "c" function from an assembly language main programme.
; ====================================================================
extern printf extern _getch extern trythis
; ====================================================================
default rel
; ====================================================================
section .code
[BITS 64] global _start
; The conventional prologue _start: mov [rsp + 8],rcx push r15 push r14 push r13 sub rsp,128 ; Stack space
; Send a C function two numbers to be added mov qword [numa],1 mov rcx,[numa] mov rdx,2 xor r8,r8 xor r9,r9 call trythis ; The return value will come back in rax
; Display the return value mov rcx,retmes mov rdx,rax xor r8,r8 xor r9,r9 call printf
; Wait for a key-press xor rcx,rcx call _getch
; Standard epilogue xor rax,rax ; add rsp,128 pop r13 pop r14 pop r15 ret
; ====================================================================
section .data
numa dq 0 retmes db 'We are now back after calling the C function; it has returned %lld',0x0a,0x0d,0
; End of Programme ===================================================
-------------------------------------------------------------------------------- /* An extremely simple "c" function */
int trythis( int numa, int numb ) { int numc; numc = numa + numb; printf( "We are now in the c function and the answer is %lld\n", numc ); return numc; } -------------------------------------------------------------------------------- c:\nasm\nasm -f win64 -Ox -Z SampleCF.err SampleCF.asm -l SampleCF.lst if errorlevel 1 goto nasmfail k: cd \"Microsoft Visual Studio 10.0"\VC call vcvarsall.bat x64 e: cl /c Simplecf.c if errorlevel 1 goto cfail link SampleCF.obj Simplecf.obj /subsystem:console /defaultlib:msvcrt.lib /defaultlib:kernel32.lib /entry:_start if errorlevel 1 goto linkfail pause goto end
:nasmfail :cfail :linkfail @echo There were errors! pause
:end --------------------------------------------------------------------------------
After assembly and compilation the resultant executable file SampleCF.exe occupies just 4096 bytes on my hard drive. In other words, the version with a single "c" main programme takes 13 times the space of the version with an essentially identical "c" function called from assembly language. Odd is it not? Fishy even perhaps.
And of course the assembly code - if it is time critical - is guaranteed to run about five times faster than the "c" code.
I may add that it is possible to make a "c" function called in this way as complex as one wishes. And I have tried opening files in the assembler section and passing the FILE pointer to a "c" function as argument - no problem at all.
|