4

Quiero hacer una función división, pero tengo problemas con la inicialización de rdx porque siempre es 0.

Hasta el momento no he intentado algo, pero no porque sea flojo sino porque no se me ocurre de inicializar rdx como parámetro manteniendo su valor ingresado.

Esté sería el código de la función.

 division proc public

     cmp rdx, 0
     je error

     mov rax, rcx

     cqo

     idiv rdx

     ret

 division endp
 
 error proc
     xor rax, rax
     ret
 error endp

Está en el ensamblador MASM x64 de visual studio, pero solo necesito saber como inicializarlo como parámetro.

Aquí dejo mi código C

#include <stdio.h>

extern int __fastcall division(int a, int b);

int main() {

    int a = division(20, 10);

    printf("%d", a);

    return 0;
}

Por si se lo preguntan ya probe con mov rbx, rdx pero el resultado es el mismo.

6
  • 2
    La inicialización de 'rdx' parece que está bien. Es el segundo parámetro. Usa un depurador para comprobarlo.... Tu código no genera una excepción 'Divide Error'?... 'cqo', para tus datos de ejemplo está borrando 'rdx'... Expansión de signo positivo... Commented el 2 jul. a las 14:02
  • 2
    Correcto, pero el convenio para 64bits también espera los dos primeros parámetros en RCX y RDX, así que en este caso daría lo mismo Commented el 2 jul. a las 15:23
  • 2
    Curioso que los comentarios borrados no aparecen en la linea de tiempo... El 'correcto' de arriba era por un comentario que ha sido borrado.... En fin.. Commented el 2 jul. a las 16:58
  • 3
    Cuando borré el comentario no había recargado la página y no vi que me respondiste. Para que se entienda, había dicho que fastcall solo se aplica a x86 learn.microsoft.com/en-us/cpp/cpp/fastcall
    – Mateo
    Commented el 2 jul. a las 17:03
  • 2
    Gracias por tu comentario... Que parecía que no sabía lo que decía :) Commented el 2 jul. a las 17:12

1 respuesta 1

3

El manual de Intel dice lo siguiente sobre idiv:

Divides the (signed) value in the AX, DX:AX, or EDX:EAX (dividend) by the source operand (divisor) and stores the result in the AX (AH:AL), DX:AX, or EDX:EAX registers.

[...]

In 64-bit mode when REX.W is applied, the instruction divides the signed value in RDX:RAX by the source operand. RAX contains a 64-bit quotient; RDX contains a 64-bit remainder.

El dividendo se encuentra formado por 2 RDX con los bits más significativos y RAX con los menos significativos. El cociente se almacena en el RAX y el resto en RDX. Por lo tanto, RDX no puede tener cualquier valor. En una división con signo, hay que extender el número que utiliza una representación de complemento a 2 y justo eso es lo que hace la instrucción CQO.

Al momento de hacer la división, rdx ya no tiene el divisor que recibió como parámetro. Considera utilizar otro registro al que copiar su valor previamente:

 mov rax, rcx
 mov rcx, rdx
 cqo
 idiv rcx
2
  • 1
    Después de leer tus comentarios detalladamente, vi cual era el error. Muchas Gracias.
    – ASMAZREG
    Commented el 2 jul. a las 21:50
  • A mí también me resolviste una duda. Gracias. @Mateo Commented el 3 jul. a las 0:41

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