3

Esté es el código de la función con .intel_syntax activado.

gnwmult8_32:
    movzbw ax, cl # Muevo el valor del registro cl al registro ax
    cbw           # Extiende el registro dl a 16 bits
    imul dl       # multiplico el valor de ax por dl y se vuelve a almacenar en ax
    ret           # fin de la función

Código en C

#include <stdio.h>
extern int __fastcall gnwmult8_32(int a, int b);
int main() {
    printf("%d", gnwmult8_32(255, 2));
    return 0;
}

Imprime 65534 cuando debería ser 510

El código funciona cuando agrego un movzbw bx, dl y multiplico los registros imul ax, bx

Se me hace raro que no haga lo mismo si se supone que extiendo dl a 16 bits con cbw

En cierto punto intente quitar cbw y el resultado era el mismo.

Intente ver el hexadecimal generado por "objdump" a través de hacer a mi archivo ASM y C archivos "obj" y combinandolos en uno solo con "ld.exe"

El desensamblado no funciono.

Luego intente usar "gbd" con el "GBD online Debugger | Compiler" y este fue lo que hice.

(Marqué imul dl como punto de quiebre)

(gdb) run
(gdb) info registers  # Verifica que ax contiene 0x00FF

(gdb) stepi  # Ejecutar imul dl
(gdb) info registers  # Verificar que ax contiene 0x01FE (510 en decimal)

El código era diferente, pero creo que en esencia lo mismo.

Código que use en GBD online.

.intel_syntax noprefix
.global main

main:
    mov cl, 255        # cl = 255
    mov dl, 2          # dl = 2
    movzbw ax, cl      # ax = 255 extendido a 16 bits
    imul dl            # ax = 255 * 2 = 510
    movzx rbx, ax        # Guardar el resultado en rbx
    mov rax, 60        # syscall: exit
    xor edi, edi       # status 0
    syscall

Después de ejecutar imul, rax debería ser 0x01FE pero es 0x55555555fffe.

Sé que rax no es lo mismo que ax pero al parecer a GBD online eso le da igual.

En ente punto no sé cual podría ser el error.

En caso de necesiten más información díganme.

4
  • 1
    Cuál es el propósito de la función? El prototipo de la función recibe 2 enteros (probablemente de 32 bits) y devuelve uno. O sea que los números que recibe tu función ya son de 32 bits, no necesitas extender el número con 0s. Con mul sin signo no necesitas utilizar cbw. Si querías hacer aritmética de 8 bits mejor usa un tipo más pequeño como char.
    – Mateo
    Commented el 21 jun. a las 15:29
  • Justamente quería usar 8 bits, pero evitar el desbordamiento con registros de 16 bits. @Mateo
    – ASMAZREG
    Commented el 21 jun. a las 21:36
  • 1
    Entonces lo ideal sería declarar la función como char(char, char)
    – Mateo
    Commented el 22 jun. a las 15:59
  • Gracias, eso haré @Mateo
    – ASMAZREG
    Commented el 22 jun. a las 17:59

1 respuesta 1

2

imul es una multiplicación con signo, al utilizar registros de 8 bits estás multiplicando al * dl... al es 255 o -1 si lo consideras un entero de 1 byte con signo y por tanto el resutado es 0xfe o -2 (-1x2 = -2).

Simplemente utiliza más precisión para tu operación:

main:
    mov    cl, 255        # cl = 255
    mov    dx, 2          # dl = 2
    movzbw ax, cx         # 
    imul   dx             # ax = 255 * 2 = 510
    movzx  rbx, ax        # Guardar el resultado en rbx
    mov    rax, 60        # syscall: exit
    xor    edi, edi       # status 0
    syscall

Ten en cuenta que ahora el resultado de la multiplicación se almacenará en DX:AX si fuera superior a 16 bits. Para tu ejemplo el resultado cabe en AX.

5
  • ¿Lo mismo aplica a la función?
    – ASMAZREG
    Commented el 21 jun. a las 7:42
  • 1
    Si. La multiplicación la hace el procesador. Es independiente de lenguaje, convention call o cualquier otra cosa. En tu función usas imul dl. dl es un registro de 8 bits y la instruccion tomara al y dl como valores de 8 bits con signo Commented el 21 jun. a las 7:45
  • ¿Pero no sé supone que tendría que usar ax para la multiplicación en vez de al? Además se supone que cbw extiende el registro dl a 16 bits. Porque si almacena un resultado, pero es demasiado grande y no hace el cálculo esperado porque quiero que 255 * 2 de como resultado 510 aunque da más de 60,000. Está sería mi última pregunta y duda. @RevistaOnlineOccam'sRazor
    – ASMAZREG
    Commented el 21 jun. a las 7:47
  • 1
    Muchísimas gracias, respondiste todas mis dudas de manera clara. Te lo agradezco mucho. @RevistaOnlineOccam'sRazor
    – ASMAZREG
    Commented el 21 jun. a las 7:56
  • 1
    imul dl multiplica al por dl y almacena el resultado en ax. al y dl se consideran con signo, independientemente de que el resultado se almacene en ax, el cual también se considerará con signo. cbw extiende el signo de al a una palabra.. básicamente afecta al registro ah el cual será cero para números positivos y 1 para negativos... Pero cuando multiplicas usas imul dl y al sigue teniendo el mismo valor. Aqui ves que tu caso es el primero Commented el 21 jun. a las 8:08

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.