ну в двух словах прмерно дложно происходить так. если умножаешь 8 байтовый регистр на 8 байтовый, то результат должен быть 16 байтовым. в команже mul это заложено изнаально. по умолчанию он в качестве операнда принимает 1 значение (8 байт пусть будет) и умножает это значение на rax. в результате ответ должен быть 16 байтовым, но регистра такого нет, поэтому результат раполагается в паре регистров, rdx - старшая часть числа, rax - младшая. при делении наоборот, если ты указываешь в качестве операнда число 8 бацтовое(делитель), то делимое располагается в двух регистрах - rdx:rax. а ответ помещаается в 8 байтовый регистр rax, а остаток от деления в rdx. вот и думай в каком случа у тя затирается регистр rdx, где ты его испортил предыдущим значение.
в код не вникал