flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
Overclick
Ups, wrong place I post it ))
|
|||
![]() |
|
revolution
We don't know what you have done. Show some code.
|
|||
![]() |
|
Walter
Isn't it usual to use the "cdq" instruction immediately before the idiv?
|
|||
![]() |
|
revolution
There are two types of idiv instruction. Which is why I asked to see the code so we can see what is being done.
I expect the error reported is division by zero, but the OP doesn't say, so we can't know for sure. Division by zero is generated whenever the result can't fit into the destination. So it happens for more cases than just a zero divisor. |
|||
![]() |
|
Overclick
I experimenting with some audio filters and forgot to clear rdx, that how I found it. There is non Zero for sure. Anyway, why OS deals with it?
|
||||||||||
![]() |
|
Overclick
Actually there have to be pair of idiv r12 idiv r13, I tried to optimise them to one divide. Anyway this filter is too slowly for me and I have better idea.
|
|||
![]() |
|
revolution
You are using the single operand version of idiv. That means it takes rdx and rax as the numerator.
What is your error? It is division by zero, right? You forgot to say. If the absolute value of rdx is greater than or equal to r12 then you will get a DivZero error. The result would be greater than 64 bits. For example if we assume that each register is a single decimal digit: 30 / 3 needs two digits for the result and can't fit a single register. |
|||
![]() |
|
Overclick
Is that means "division by zero" where result doesn't feet to single register? Interesting...
Why OS then? |
|||
![]() |
|
revolution
The OS receives all CPU generated traps. It is how the CPU works.
|
|||
![]() |
|
Overclick
Where to read about another implementation of idiv? I know only one. Don't you mistake with imul instruction?
|
|||
![]() |
|
Overclick
Quote:
You right, cqo for rdx |
|||
![]() |
|
Furs
Overclick wrote: If I don't clear rdx before idiv, the next command will never run. Not clearing rdx means you have garbage values there. Even if it didn't crash, your results would be totally wrong. |
|||
![]() |
|
Overclick
Quote:
As I said I forgot to do that. Just interested why it can't be processed by developer as usual flag changing operation. |
|||
![]() |
|
revolution
Overclick wrote: Just interested why it can't be processed by developer as usual flag changing operation. If you use the FPU then you can set the control register to generate infinity. But no such equivalent exists for the integer core. If you need to avoid the trap then you can compare rdx to the denominator and skip the division. Code: ; for positive numbers cmp rdx, r12 jae .too_large idiv r12 ;... .too_large: ;... |
|||
![]() |
|
Overclick
Too slowly all of that. Sadly there is not much options to divide integer, no one for SSE. Only bit shifting can help a little. I return to float, it working slower but need less operations to realise all I want. Classical FPU is absolutely slowmo. 10 times slower than integer when SSE just twice for single dword. Fully packed is ok.
|
|||
![]() |
|
FlierMate
I noticed the same (in 32-bit):
Code: 0: A1 04 10 40 00 MOV EAX,DS:0x401004 5: 31 D2 XOR EDX,EDX 7: BB 02 00 00 00 MOV EBX,0X2 C: F7 FB IDIV EBX E: A3 04 10 40 00 MOV DS:0x401004,EAX Generated for my own language: Code: LET b= 20 b /= 2 Have to clear EDX. Thanks to this thread, now I understand far better. |
|||
![]() |
|
revolution
If you use IDIV then you might want to consider using CDQ instead of XOR EDX,EDX
Or alternatively if EAX is unsigned, use DIV, and keep the XOR EDX,EDX |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.