简体   繁体   中英

Assembly How to translate opcode DIV to C Code

Hey I know I been asking alot of questions.. but not much resources on this on google so hopefully this will help future people who attempt to do similar projects, I always google solutions as well, but I never search passed first page.

I looked at that Intel manual Alex posted, seems pretty alien to me http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-2b-instruction-set-az-manual.html

So I thought I knew how a simple DIV opcode worked. Since it's just divide after all. I had no difficulty adding ADD , SUB , of course IMUL had problems you guys helped me out on that one. Seems DIV falls into the same category as IMUL in terms of difficulty.

Well without using the manual just doing self debugging tests with OllyDbg.

I found out answer of division is always stored in EAX . Figured out the remainder is also kept who knew, stored in EDX .

Which from studying this algorithm is extremely important who knew, someone would use the remainder of a random number division to generate a switch from 0-10 pretty clever.. But still my question.

It's already strange I never thought of hexadecimal numbers of being divided would have remainders decimal points don't even belong in them.

DIV ECX

would be like

regs.d.eax /= regs.d.ecx;
regs.d.edx = regs.d.eax % regs.d.ecx;

I was thinking maybe getting remainder first.. will simply things.

regs.d.edx = regs.d.eax % regs.d.ecx;
regs.d.eax /= regs.d.ecx;

Okay I hardly work with mathematical programming so it's a bit confusing for me. I'm more of a guy that would store the result in a string then split it by decimal point and that's how I would get the remainder yeah I know it's slow and it's taking the easy path out.. and I myself am against using string operations in a mathematical code.

Ok well.. looking at that C code I put there.. probably have to store both EAX and ECX before division happens in temporary variables.. or do the remainder code first.. then division code second. I don't know.

Well I'll see maybe you guys can provide me with a better answer perhaps it cannot be done in one line but maybe I made a few mistakes.. I can't really test the things I do right now due to many other things I have to fix before I can even compile the software.

The manuals are no easy reading, true, but they have all the answers to your questions (well, most of them, there are occasional omissions and mistakes in the docs).

One thing you're missing in your guessed algorithm is that DIV typically divides 2N bits by N bits, that is, when you do DIV ECX you divide a 64-bit unsigned value contained in EDX:EAX by a 32-bit unsigned value in ECX. The quotient is then stored in EAX and the remainder in EDX.

You should also remember about the possibility of a division overflow (in this case EDX>=ECX is the condition for it) and flags that the instruction modifies in the EFLAGS register.

I think a reasonably fair translation would be:

  int16_t a=42,b=7;
  int16_t div = a/7;
  int16_t remainder = a - (div*b);

In practice, this may, or may not be equivalent to remainder = a % b (I'd need to look up the standard specs). It gets more interesting if you consider carefully what happens with negative numbers.

All that said, the decimal point never comes into play, so I don't see why you mention it in the post.

perhaps it cannot be done in one line [...]

I highly suspect the compiler will pick up on the reuse of subexpressions, and automatically use the remainder from (E)DX when applicable. (this is rather trivial optimization for a compiler)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM