flat assembler
Message board for the users of flat assembler.
Index
> Main > Syntax of immediate operand for div? |
Author |
|
jkhjklhgl 04 Mar 2016, 19:05
div 2
gives Error: invalid operand How should it be written? |
|||
04 Mar 2016, 19:05 |
|
revolution 04 Mar 2016, 23:38
Code: mov ecx,2 div ecx ;for dword div ecx ;for word idiv eax,ecx,2 ;for immediate only idiv is available |
|||
04 Mar 2016, 23:38 |
|
revolution 05 Mar 2016, 09:17
Xorpd! wrote: Are you sure about that? Intel's docs indicate a syntax like the above for IMUL, but not DIV nor IDIV. There is AAM imm8 which performs a divide of AH:AL by an immediate byte, but it doesn't work in 64-bit mode. |
|||
05 Mar 2016, 09:17 |
|
taeyun 07 Mar 2016, 06:10
you need register.
if you don't like this, you can trick your self with macro. div register version:(you can replace div with idiv for signed value) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if you want to divide 0xff by 0x02(which is 1 byte divisor) you need to put 0xff to ax, put 0x02 to other 1 byte register(such as bl), div bl now you have quotient in al remainder in ah ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if you want to divide with 2 byte divisor such as 0x0222, you can divide 4 byte (such as 0xaabbccdd) to do so, put 0xaabb to dx put 0xccdd to ax put 0x0222 to other 2 byte register(such as bx), div bx now you have quotient in ax remainder in dx ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if you want to divide with 4 byte divisor such as 0x00112233, you can divide 8 byte (such as 0xaaaabbbbccccdddd) to do so, put 0xaaaabbbb to edx put 0xccccdddd to eax put 0x00112233 to other 4 byte register(such as ebx), div ebx now you have quotient in eax remainder in edx it is quiet handy to use CDQ instruction. CDQ extend eax value to edx. for instance, if you want to divide 0xaaaabbbb with 0xddddeeee, you can: mov eax, 0xaaaabbbb CDQ mov ebx, 0xddddeeee div ebx now you have quotient in eax and remainder in edx ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ div macro version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;;put value you want to divide into eax macro mydiv reg { cdq push ebx mov ebx, reg div ebx pop ebx } and use it mydiv 2 |
|||
07 Mar 2016, 06:10 |
|
Furs 08 Mar 2016, 15:14
An alternative to division by a constant is to do a "inverse" multiplication, since a constant is "known" and can be converted to an inverse multiplication by another constant which is faster.
The other reason to use div instead of mul is if you are using the highest bit-width available on your CPU mode for a division (for x86 32-bit, that is 64-bit, and for x86-64 64-bit, that is 128-bit; in both cases it's made of registers edx:eax and rdx:rax respectively). For example, dividing rdx:rax by a certain constant requires div. But if you only want to divide eax in 32-bit, you can just treat it as a fixed point multiplication, do the 64-bit multiplication, and take edx as the result (not eax), aka the higher half. Mathematically, it is equivalent to: a * (b / 2^32) You see b can be an integer but because it is divided by 2^32, you get a division. However the order of operations can be like this: (a*b) / 2^32 The last division/bit shift isn't even needed since that simply means the 'edx' part of the edx:eax composite result. Note that depending on the constant and its reciprocal, there may be round-off errors you'll have to compensate. For example, division by 3 has the "inverse mul" constant started from: 2^32 / 3 = 0x55555555 Turns out this isn't very precise due to roundoff errors, so what people did was to increase the range to 33 bits and round up, and then right shift 'edx' by 1 (to divide by 2^33 instead of 2^32). For example (the +1 is due to rounding up the .(6) fraction): 2^33 / 3 + 1 = 0xAAAAAAAB Code: ; eax = your number mov edx, 0xAAAAAAAB mul edx shr edx, 1 ; edx = output, eax/3 |
|||
08 Mar 2016, 15:14 |
|
Tomasz Grysztar 08 Mar 2016, 15:54
Furs wrote: An alternative to division by a constant is to do a "inverse" multiplication, since a constant is "known" and can be converted to an inverse multiplication by another constant which is faster. You can find that post (and the complete discussion) archived at http://www.asmcommunity.net/forums/topic/?id=21308#post-161744 I don't know if that archive is reliable, and it does not preserve the original formatting well, so I'm also copying my old post here: Tomasz Grysztar in 2005 wrote: If you want to divide by the odd number, and you know the number you want to divide is divisible without remainder, you can do this by multiplying by "magic" number and take the LOW half of the result, without need to do any shifts etc. |
|||
08 Mar 2016, 15:54 |
|
Furs 08 Mar 2016, 16:18
Well I learned something new, never heard of 2-adic numbers before this, thanks for the excellent post. It's superior to the fixed point multiplication since it doesn't need twice the bit width as the original so it can be used with IMUL like you said
|
|||
08 Mar 2016, 16:18 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.