Perdonen la trivialidad... pero un programa en C, por ejemplo, el siguiente:
#include <stdio.h>
int main()
{
printf ("Im the output.");
getchar ();
return 0;
}
y creo que imposiblemente mas exactamente el mismo programa, pero en ensamblador:
.686
.model FLAT
includelib \masm32\lib\msvcrt.lib
printf proto C, :dword
getchar proto C
exit proto C, :dword
.data?
dd ?
.data
__0 db "Im the output.", 0
.code
start:
call main
invoke exit, 0
main proc
invoke printf, offset __0
invoke getchar
ret
main endp
end start
Producen una salida con una diferencia de ciento veintinueve mil seiscientos cuarenta y dos (129 642) bytes ¡Eso seria un 85.40% mayor, para el mismo algoritmo! ¡Que locura!
¿Por que existe esta diferencia tan abismal?
¿Es la diferencia siempre de este tamaño en terminos porcentuales, o la diferencia existe hasta cierto punto?
Saludos.
El primero tiene la RTL de C completa enlazada estaticamente dentro del ejecutable y el segundo la enlaza dinamicamente (esta es la RTL de C del VC++ en una DLL: msvcrt.dll).
Asi rapidamente vas a notar una diferencia grande: cl /O1 /MD hello.cpp
Cita de: Eternal Idol en 20 Febrero 2021, 19:49 PM
El primero tiene la RTL de C completa enlazada estaticamente dentro del ejecutable
Eso no me lo imagine...
Gracias por tu respuesta.
Saludos.
De nadas ::)
https://foro.elhacker.net/programacion_cc/eliminar_basura_de_los_exes_compilados_en_c-t299411.0.html
Cita de: Eternal Idol en 20 Febrero 2021, 21:26 PM
https://foro.elhacker.net/programacion_cc/eliminar_basura_de_los_exes_compilados_en_c-t299411.0.html
Citar #define _WIN32_WINNT 0x0403
#define WIN32_LEAN_AND_MEAN
#pragma optimize("gsy", on)
#pragma comment(linker,"/RELEASE")
#pragma comment(linker, "/IGNORE:4108")
#pragma comment(linker, "/FIXED")
#pragma comment(linker, "/STUB:stub.exe")
#pragma comment(linker, "/MERGE:.rdata=.data")
//#pragma comment(linker, "/MERGE:.reloc=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma comment(linker, "/NODEFAULTLIB")
#pragma comment(linker, "/ENTRY:DllMain")
#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")
#pragma pack(1)
¿Me explicarias que exactamente esta pasando aqui con el linker? ¿Que es "gsy"?
¿Por que en el primer programa la libreria se supone estatica y en el segundo dinamica? ¿Cada vez que declaro
ID proto C, ... el ensamblador añade un GetProcAddress o algo asi?
Ese pragma es para el compilador:
https://docs.microsoft.com/en-us/cpp/preprocessor/optimize?view=msvc-160
Por el tamaño pero depende de la configuracion del proyecto y lo que termine por pasar en linea de comandos:
https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=msvc-160
Si probaras la que te deje verias la diferencia usando el mismo codigo fuente:
cl /O1 /MD hello.cpp
No, pero tu ejecutable tiene por cada uno de los PROTO un funcion importada. Compara los 2 ejecutables con https://www.dependencywalker.com/
PD. GetProcAddress seria enlace dinamico en tiempo de ejecucion y la otra en tiempo de carga (esta en el PE el enlace en si mismo):
https://docs.microsoft.com/en-us/windows/win32/dlls/using-run-time-dynamic-linking
(https://i.imgur.com/erT6WDp.png)
Asi se ha quedado...
A ver si entendi. En el caso del programa en C, el compilador incluye toda la libreria estatica MSVCRT en el ejecutable, en cambio, en el programa en ASM, el programa usa el codigo de la DLL MSVCRT.DLL, ¿No?
A lo demas tendre que dedicarle un poco de tiempo.
[youtube=640,360]https://www.youtube.com/watch?v=nn2FB1P_Mn8[/youtube]
;D
A todo el mundo le funciona ...
(https://i.imgur.com/qjh3SPS.png)
Si, al enlazar una libreria estatica (.LIB de codigo) el primer programa contiene todo el codigo de la RTL en su ejecutable, el segundo simplemente enlaza dinamicamente la DLL (con un .LIB de importacion).