Foro de elhacker.net

Programación => ASM => Mensaje iniciado por: alienxz77b en 18 Octubre 2021, 08:00 am



Título: Como puedo hacer que este código ensamblador funcione?
Publicado por: alienxz77b en 18 Octubre 2021, 08:00 am
Hola :), primero gracias por tomarse el tiempo para leer esta pregunta  ;D

Tengo este código ensamblador de NASM que realice para probar una teoría de condicionales
el chiste es que no puedo hacerlo correr debido a un problema que me sale:
Código
  1. %include "io.inc"
  2. %macro print 1
  3.    push eax
  4.    push ecx
  5.    mov eax, %1
  6.    mov ecx, -1
  7.    while:
  8.    add ecx, 1
  9.    cmp byte [eax+ecx], 0
  10.    jmp PRINT_CHAR [eax+ecx]
  11.    jne while
  12.    pop ecx
  13.    pop eax
  14. %endmacro
  15. %macro strcpy 2
  16.    push eax
  17.    push ecx
  18.    push edx
  19.    mov eax, %1
  20.    mov edx, %2
  21.    mov ecx, -1
  22.    .while:
  23.    add ecx, 1
  24.    cmp byte [eax+ecx], 0
  25.    mov [edx+ecx], byte [eax+1]; al parecer en esta linea de codigo esta el error  :-[
  26.    jne .while
  27.    je print edx
  28.    pop edx
  29.    pop ecx
  30.    pop eax
  31. %endmacro
  32. ;segment data
  33. section .data
  34. msg db "Hola", 13, 0
  35. msg2 db "     ", 0
  36. section .text
  37. global CMAIN
  38. CMAIN:
  39.    xor eax, eax
  40.    call strcpy msg, msg2
  41.    ret 0
Error:

C:\Users\Windows\AppData\Local\Temp\SASM\program.asm:40: error: invalid combination of opcode and operands
gcc.exe: error: C:\Users\Windows\AppData\Local\Temp\SASM\program.o: No such file or directory

No se que hacer para solucionarlo, programo en windows bajo el IDE de SASM
Agradezco toda la ayuda  ;D
Edit:
En la linea 25 era:
Código
  1.    mov [edx+ecx], byte [eax+ecx]; al parecer en esta linea de codigo esta el error  :-[
:xD


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Usuario887 en 18 Octubre 2021, 17:13 pm
C:\Users\Windows\AppData\Local\Temp\SASM\program.asm:40: error: invalid combination of opcode and operands

Estas usando la sintaxis de invoke:

https://docs.microsoft.com/en-us/cpp/assembler/masm/invoke?view=msvc-160 (https://docs.microsoft.com/en-us/cpp/assembler/masm/invoke?view=msvc-160)

Mas informacion sobre la dicotomia entre call e invoke:

http://www.asmcommunity.net/forums/topic/?id=29146 (http://www.asmcommunity.net/forums/topic/?id=29146)

En la linea cuarenta.

Eso traducido a un call corriente con una convencion de llamada de C:

https://en.wikipedia.org/wiki/X86_calling_conventions (https://en.wikipedia.org/wiki/X86_calling_conventions)

Seria:

Citar
push addr msg2
push addr msg
call strcpy

Deberia funcionar, aunque no lo probe.
Suerte.  :-*



PD:

Si quisieras usar invoke:

Citar
invoke strcpy msg, msg2


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: alienxz77b en 20 Octubre 2021, 02:20 am
Hola gracias por responder  ;D, al parecer sigue tirando el mismo error  :-\


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Eternal Idol en 20 Octubre 2021, 02:56 am
Si, el mov de la linea 25 no es factible pero te recomiendo revisar y depurar todo, no encuentro el sentido a usar eax + 1 en cada iteracion (eso en este caso copia el segundo caracter de una cadena siempre).

Esto es equivalente a lo que intentabas:
Código
  1. mov bl, [eax+1]
  2. mov [edx+ecx], bl


PD. invertiste el orden de los parametros de strcpy, el primero deberia ser el destino y el segundo la fuente.


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: alienxz77b en 20 Octubre 2021, 17:39 pm
Ya arregle el código  :D:
Código
  1. %include "io.inc"
  2. %macro print 1
  3.    push eax
  4.    push ecx
  5.    mov eax, %1
  6.    mov ecx, -1
  7.    while:
  8.    add ecx, 1
  9.    cmp byte [eax+ecx], 0
  10.    jmp PRINT_CHAR [eax+ecx]
  11.    jne while
  12.    pop ecx
  13.    pop eax
  14. %endmacro
  15. %macro strcpy 2
  16.    push eax
  17.    push ecx
  18.    push edx
  19.    push SI
  20.    mov edx, %1
  21.    mov eax, %2
  22.    mov ecx, -1
  23.    .while:
  24.    add ecx, 1
  25.    cmp byte [eax+ecx], 0
  26.    mov SI, [eax+ecx]
  27.    mov [edx+ecx], SI
  28.    jne .while
  29.    pop SI
  30.    pop edx
  31.    pop ecx
  32.    pop eax
  33. %endmacro
  34. ;segment data
  35. section .data
  36. msg db "Hola", 13, 0
  37. section .bss
  38. msg2 resb 100
  39. section .text
  40. global CMAIN
  41. CMAIN:
  42.    xor eax, eax
  43.    strcpy msg2, msg
  44.    print msg2
  45.    ret 0
Gracias por su ayuda  a todos los que respondieron ;D
Nos vemos  ;)


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Eternal Idol en 20 Octubre 2021, 18:35 pm
Bien, ahora tiene logica la copia pero sigue teniendo exactamente el mismo bug que en el otro hilo al escribir con print y es opuesto al standard de C el strcpy.


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: alienxz77b en 20 Octubre 2021, 23:24 pm
Según Wikipedia:
https://es.wikipedia.org/wiki/Strcpy (https://es.wikipedia.org/wiki/Strcpy)
 La sintaxis de strcopy esta bien  ;D
Codigo sin bugs o algo parecido (puede que tenga errores  :()
Código
  1. %include "io.inc"
  2. %macro print 1
  3.    push eax
  4.    push ecx
  5.    mov eax, %1
  6.    mov ecx, -1
  7.    while:
  8.    add ecx, 1
  9.    cmp byte [eax+ecx], 0
  10.    jmp PRINT_CHAR [eax+ecx]
  11.    jne while
  12.    pop ecx
  13.    pop eax
  14. %endmacro
  15. %macro strcpy 2
  16.    push eax
  17.    push ecx
  18.    push edx
  19.    push SI
  20.    mov edx, %1
  21.    mov eax, %2
  22.    mov ecx, -1
  23.    .while:
  24.    add ecx, 1
  25.    cmp byte [eax+ecx], 0
  26.    mov SI, [eax+ecx]
  27.    mov [edx+ecx], SI
  28.    jne .while
  29.    pop SI
  30.    pop edx
  31.    pop ecx
  32.    pop eax
  33. %endmacro
  34. ;segment data
  35. section .data
  36. msg db "Hola", 0
  37. section .bss
  38. msg2 resb 100
  39. section .text
  40. global CMAIN
  41. CMAIN:
  42.    xor eax, eax
  43.    strcpy msg2, msg
  44.    print msg2
  45.    ret 0


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Eternal Idol en 21 Octubre 2021, 00:18 am
Mala mia, lo cambiaste y ahora si el primer parametro es el destino y el segundo la fuente, el bug del print sigue ahi, escribe el 0 terminador.


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: alienxz77b en 25 Octubre 2021, 05:14 am
De hecho solo se pueden imprimir cadenas usando el terminador nulo como en C  ;D


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Eternal Idol en 25 Octubre 2021, 09:22 am
No, una cosa es ENCONTRARLO para frenar y otra muy diferente escribir el 0, eso hace tu codigo y ninguna funcion para escribir una cadena en pantalla lo hace  ;) ¿Para que le sacaste el 13 a msg?  ;D ;D ;D ¿Para que no pasara esto?

(https://i.ibb.co/mN3qDL5/bug.png)

¿Crees que si llamo a printf con "Hola\r" como parametro pasa eso acaso? Necesitaria llamar a putc con el 0 para que lo escribiera y pasara lo mismo que con tu macro print.

PD. Si se puede.
Código
  1. char nnts[] = { 'N', 'E', 'W', 'B', 'I', 'E', 0xCC, 0xCC };
  2. printf("%.*s", 6, nnts);


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Usuario887 en 25 Octubre 2021, 11:49 am
%.*s

Perdona el cambio de tema, Eternal Idol, pero una pregunta rapida... ¿Esto que sintaxis tiene?


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Eternal Idol en 25 Octubre 2021, 13:57 pm
https://www.cplusplus.com/reference/cstdio/printf/

"*   The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted."


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Usuario887 en 25 Octubre 2021, 17:29 pm
https://www.cplusplus.com/reference/cstdio/printf/

"*   The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted."

No sabia que se podia limitar eso... Un riesgo menos.

Gracias


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Eternal Idol en 25 Octubre 2021, 17:31 pm
No sabia que se podia limitar eso... Un riesgo menos.

Gracias

De nada  ::)


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: alienxz77b en 25 Octubre 2021, 22:36 pm
Creo que esta es la solucion:
Código
  1. %include "io.inc"
  2. %macro print 1
  3.    push eax
  4.    push ecx
  5.    mov eax, %1
  6.    mov ecx, 0
  7.    while:
  8.    add ecx, 1
  9.    cmp byte [eax+ecx], 0
  10.    jmp PRINT_CHAR [eax+ecx-1]
  11.    jne while
  12.    pop ecx
  13.    pop eax
  14. %endmacro
  15. %macro strcpy 2
  16.    push eax
  17.    push ecx
  18.    push edx
  19.    push SI
  20.    mov edx, %1
  21.    mov eax, %2
  22.    mov ecx, -1
  23.    .while:
  24.    add ecx, 1
  25.    cmp byte [eax+ecx], 0
  26.    mov SI, [eax+ecx]
  27.    mov [edx+ecx], SI
  28.    jne .while
  29.    pop SI
  30.    pop edx
  31.    pop ecx
  32.    pop eax
  33. %endmacro
  34. ;segment data
  35. section .data
  36. msg db "Hola", 13, 0
  37. section .bss
  38. msg2 resb 100
  39. section .text
  40. global CMAIN
  41. CMAIN:
  42.    xor eax, eax
  43.    strcpy msg2, msg
  44.    print msg2
  45.    ret 0
;D


Título: Re: Como puedo hacer que este código ensamblador funcione?
Publicado por: Eternal Idol en 25 Octubre 2021, 23:25 pm
Sigue teniendo fallos; SI es un registro 16 bits por lo que la condicion para terminar el bucle se basa en un byte pero lees y escribis 2 bytes por cada iteracion, eso carece de sentido, es ineficiente (sobrescribe datos) y lleva a problemas, por ejemplo, teniendo una cadena vacia:

Código
  1. msg db 0
  2. oops db "BUG", 0

El strcpy no funciona bien, copia la B de oops en msg2  :rolleyes: Estas leyendo mas alla de los limites de la cadena.

Ademas si por ejemplo en lugar de usar msg2 como parametro a print uso msg. ¿Que crees que pasa? Lee un buffer que no deberia leer: oops.

(https://i.imgur.com/ytnbQes.png)