hola
Habra algun problema si programo en ASM con WinMain@16, lo que pasa es que logre hacer un printf, pero lo hice con WinMain, pero no se si eso esta mal, porque pueda pesar mas bytes, se toman cosas extras de gcc o algo que lo haga menos eficiente?
tambien como decidi usar Nasm porque la mayor parte del tiempo uso linux, y virtualizo windows entonces se me hace mas sencillo mejor nasm
pero bueno, ya me explicaron en fasm como importar, pero en nasm, ¿como importo las DLL y las apis?, en google encontre un ejemplo pero no me sirvio y de alli ya no vi mas formas
y una pregunta
si yo hago esto
push ebp
mov ebp, esp
sub esp, 10
bueno, tengo entendido que de esta forma, meto en la base lo que haya en el stack, pero cuando se usan funciones, esp vuelve a su estado normal? o eso no pasa?
por ejemplo
push ebp
mov ebp, esp
sub esp, 12
........................... ; codigo
funcion:
mov eax, [esp + 0x08]
si hago esto, ebp sigue valiendo lo mismo y estoy tomando el parametro que meti en el DWORD 8 de los 12 que tome de esp?, o al hacer un nueva funcion, esp regresa a como estaba y estoy tomando el segundo parametro despues de RET?
salu2
hay poca gente que usa nasm, y en tu ejemplo en realidad lo más recomendable para acceder a las variables locales
o a los parametros es usar ebp, no esp porque con una alteracion de la pila ya perder la cuenta que llevabas en la pila
ademas para eso se hace el marco de la pila al principio y se restaura al final.
y no se pero no entiendo eso de
funcion:
mov eax, [esp + 0x08]
por lo de la etiqueta, no se si es por ponerle un nombre o porque de verdad así crees que se hace una funcion, tambien depende
de la convencion de llamada de la funcion, si es para una API son stdcall solo las llamas y la pila queda intacta al retorno, así como
estaba antes de llamar a la funcion
También sería recomendable que uses el macro PROC de NASM, que permite tanto la creación del stack frame como la definición de variables locales.
En un stack frame tanto las variables locales como los parámetros de la función deben ser apuntados por el registro EBP en vez de ESP, ya que cualquier instrucción como push/pop podría alterar la dirección de memoria apuntada por el registro ESP. Recuerda que tanto EBP como ESP no volverán a recuperar su valor previo mágicamente, por lo que tienes dos alternativas (LEAVE y MOV ESP, EBP/POP EBP).
push 0
push 1
call fnExample
ret
fnExample:
push ebp
mov ebp, esp
sub esp, 8 ; LOCAL DWORD, DWORD
mov dword ptr[ebp-0x04], 0 ; LOCAL 1 = 0
mov dword ptr[ebp-0x08], 1 ; LOCAL 2 = 1
mov eax, dword ptr[ebp+0x08] ; EAX = Parámetro 1 = 1
mov eax, dword ptr[ebp+0x0C] ; EAX = Parámetro 2 = 0
leave
retn 2*4 ; Número de parámetros*sizeof.DWORD
Lo de las imports imagino que debe depender del linker, aunque, ¿podrías ser más específico con el problema que tienes con las DLL?
bueno de mi primera pregunta lo que sucede es que hice esto, se me hace mas facil compilar nasm con gcc usando WinMain, pero no se que tan bueno sea
[BITS 32]
section .data
mundo db 'Hola mundo!',0
section .text
extern _printf
extern _ExitProcess@4
global _WinMain@16
_WinMain@16:
push mundo
call _printf
push 0
call _ExitProcess@4
ret 16
bueno, ya instale MASM32, hay alguno cambios, quise hacer un MessageBox y despues de 20 mensajes de error, no sabia que se tenia que poner offset a las cadenas, :P
y con lo segundo
es que me surgio la duda de que si yo hago esto
push ebp
mov ebp, esp
sub esp, 12
y despues necesitara hacer algo con un funcion, por ejemplo, si meto datos en ebp, quedaria algo asi
ebp-0x0C -> parametro 1
ebp-0x08 -> parametro 2
pero si hiciera una funcion nueva, y luego usara esp + 0x08, estaria usando el parametro de ebp-0x08 ó estaria usando el parametro de ebp+0x08, por ejemplo
push ebp
mov ebp, esp
sub esp, 12
ebp-0x0C -> parametro 1
ebp-0x08 -> parametro 2
-----------------------------
ebp+0x08 -> parametro 1
ebp+0x0C -> parametro 2
call funcion
funcion:
mov eax, [esp+ 0x08] --> estaria usando el parametro 2 - ebp-0x08?
---------------------------------------
mov eax, [esp+ 0x08] --> estaria usando el parametro 1 - ebp+0x08?
Cual estaria usando, el parametro 1 de ebp+0x08 o el prametro 2 de ebp-0x08, o ninguna de las 2?
espero sea mas entendible, pero no encuentre otra forma de explicarlo, sino pues nimodo, ya vere como investigo, gracias por las respuestas
salu2 ;D
hago cuenta y caso que sabes como deberia ser y respondiendo a tu pregunta, tú pila quedaria así despues de tu "call funcion":
ebp->ebp old
local1
local2
local3
esp->return to caller
free
free
....
ahora sumamos 8 como dices a esp y estariamos accediendo a local2, simple