Está en la página 1de 3

Capitulo3

Hola,mundo!!
VamosautilizarelfamosoejemplodellibroTheCprogrammingLanguage.

#include<stdio.h>
intmain(){
printf("hello,world\n");
return0;
}

3.1x86

3.1.1MSVC
VamosacompilarenMSVC2010:

Cl1.cpp/Fa1.asm
(/FaCreaunarchivodelistaquecontieneelcdigodeensamblado.)
Listado3.1:MSVC2010

CONSTSEGMENT
$SG3830DB'hello,world',0AH,00H
CONSTENDS
PUBLIC_main
EXTRN_printf:PROC
;Functioncompileflags:/Odtp
_TEXTSEGMENT
_mainPROC
pushebp
movebp,esp
pushOFFSET$SG3830
call_printf
addesp,4
xoreax,eax
popebp
ret0
_mainENDP
_TEXTENDS
MSVCproducelistadodeensambladoenintelsintaxis.LadiferenciaentreintelsintaxisyAT&T
sintaxissediscutirenelpunto3.13delapagina13.
Elcompiladorgeneraelarchivo,1.obj,elcualestavinculadocon1.exe.Ennuestrocaso,elarchivo
contienedossegmentos:CONST(paradatosconstantes)y_TEXT(paracdigo).
Lacadenahello,worldenC/C++tienetypeconstchar[][Str13,p176,7.3.2],peronotienesupropio
nombre.Elcompiladorlonecesitaparahacerfrentealacadenaporloquedealgunamanerasedefine
elnombreinterno$SG3830paraello.
Esporelloqueelejemplosepuedereescribirdelasiguientemanera:
#include<stdio.h>
constchar$SG3830[]="hello,world\n";
intmain(){
printf($SG3830);
return0;
}
Vamosdetrsalcdigolistadoenensamblador.Comonosotrospodemosver,lacadenaesterminada
porun0,queesestandarparalascadenasdeC/C++.ParamasinformacindelascadenasenC:57.1.1
enlapagina925.
Enelsegmentodecdigo,_TEXT,solohayunafuncinhastael:main().Lafuncinmain()comienza
conelcdigodeprlogoyterminaconelcdigodeeplogo(aligualquecasitodaslasfunciones).
Traselprologovemoslallamaalafuncinprintf()funcin:CALL_printf.Antesdelallamadaala
direccindelacadena(ounpunteroaella)quecontienenuestrosaludocolocadoenlapila(stack)con
laayudadelainstruccinPUSH.
Cuandolafuncinprintf()devuelveelcontrolalafuncinmain(),ladireccindelacadena(oun
punteroaella)siguesiendoenlapila.Puestoquenolonecesitamosms,elpunterodepila(elregistro
ESP)necesitasercorregido.
ADDESP,4significaaadir4alvalorderegistroESP.Porque4?dadoqueesteesunprogramade
32bits,necesitamosexactamente4bytesdedireccinparapasaratravsdelapila.Sisetratade
cdigox64necesitaramos8bytes.ADDESP,4esefectivamenteequivalentealregistroPOP,perosin
utilizarningnregistro.
Conelmismofin,algunoscompiladores(comoelcompiladordeCdeIntel)puedenemitirPOPECX
enlugardeADD(porejemplo,unpatrndeestetipopuedeobservarseenelcdigoOracleRDBMSya
quesecompilaconelcompiladorIntelC).Estainstruccintieneelmismoefectoperoelcontenidodel
registroECXsesobrescribir.ElcompiladorIntelCprobablementeusaPOPECXdesdecdigode
operacindeestainstruccinporqueesmscortoqueADDESP,x(1byteparaPOPcontra3parael
ADD).

HeaquunejemplodelusodePOPenlugardeADDdeOracleRDBMS:
listado3.2:OracleRDBMS10.2Linux(archivoapp.o)
.text:0800029Apushebx
.text:0800029BcallqksfroChild
.text:080002A0popecx
Despusdellamaraprintf(),elcdigooriginalC/C++contieneladeclaracinderetorno0return0
comoresultadoparalafuncinmain().Enelcdigogeneradoestoseimplementaporlainstruccin
XOR EAX, EAX. XOR es de hecho simplemente "O exclusivo"pero los compiladores utilizan a
menudoenlugardeMOVEAX,0denuevo,yaqueesuncdigodeoperacinunpocomscorto(2
bytesparaXORcontra5paraMOV).
AlgunoscompiladoresemitenSUBEAX,EAX,loquesignificarestarelvalordelaEAXapartirdel
valorenEAX,que,encualquiercaso,dacomoresultadocero.
LaltimainstruccinRETdevuelveelcontrolalapersonaquellama.GeneralmenteestoesC/C++
CRTcdigo,que,asuvez,devuelveelcontrolalsistemaoperativo.

3.1.2GCC
AhoravamosatratardecompilarelmismocdigoC/C++enelcompiladorGCC4.4.1enLinux:
gcc1.co1Acontinuacin,conlaayudadeladesensambladorIDA,vamosavercmosehacreadola
funcinmain().IDA,comoMSVC,usaIntelsyntax.
Listado3.3:cdigoenIDA
mainprocnear
var_10=dwordptr10h
pushebp
movebp,esp
andesp,0FFFFFFF0h
subesp,10h
moveax,offsetaHelloWorld;Hello,world\n
mov[esp+10h+var_10],eax
call_printf
moveax,0
leave
retn
mainendp
El resultado es casi lo mismo. La direccin del String(cadena) Hello , world(se guarda en el
segmentodedato)escargadoenelprimerregistroEAXyentoncesesguardadoenelSTACK(pila).En
lasuma,lafuncinprologocontieneANDESP,0FFFFFFF0hestainstruccinalineaelregistroESP
valorsobreunlimitede16byte.Esteresultadoentodoelvalorenlapilaestaalineadadelamisma
manera(ElCPUlorealizamejorsielvalorestaentransaccinconunaubicacinenunadireccinde
memoriaalienadaen4byteo16bytecomolimite).
SUBESP,10hubicado16bytes enelSTACK(pila). Aunquecomonosotrospodemos observar
adelante,solo4sonnecesariosaqui.

Estoporqueeltamaodelalocalizaciondelstacktambinestalineadoenunlmitede16bytes.

También podría gustarte