-3

I am confused with one semantics of 32-bit x86 imul opcode. Here is an example:

mov  eax, 0x0fffffff
mov  ebx, 0x0fffffff
imul eax, ebx          <---- eax??

It seems that as 0x0fffffff * 0x0fffffff is equal to 0xffffffe0000001, greater than 0xffffffff, so eax should be assigned to 0xe0000001 after the imul.

So here is my question, where does the higher bits (0x00ffffff) go? Does cpu use, e.g., edx to store the higher bits? Or it just sets the overflow flag?

lllllllllllll
  • 8,519
  • 9
  • 45
  • 80

1 Answers1

1

The tag wiki contains a list of resources that you can use to look up information on various instructions. For example, searching for IMUL on http://www.felixcloutier.com/x86/ leads you to http://www.felixcloutier.com/x86/IMUL.html.

So it depends, how your assembler will compile it, if two operand variant is used, then result is truncated, if single operand (IMUL ebx) is used, then result is in edx:eax.

About flags: probably debug to be sure, but the two operand version, if I'm reading it correctly will set CF/OF when the result is truncated, so in your case CF=1, OF=0? (unsigned trunc, signed not overflow).


After 3h later... It occurred to me, that I actually should search again for some nice linux debugger, like "TD" from Borland in DOS era, because it may have be handy to have one.

There's of course the gdb always around, but I can't get to like it (especially as it usually goes with AT&T syntax, which I personally dislike).

So I tried "ddd" (Data Display Debugger), directly available in Ubuntu repositories, but it looks a bit old (yeah, MOTIF, if you know, what I mean, if you never heard MOTIF, then you are not old enough). And it's gdb based... Probably worth of mention here, for people who want to go in GNU path, but I searched further.

And I ended up downloading and compiled edb-debugger. After few tries I got it to compile on my older ubuntu, run it .. and... that's IT. Just few clicks in preferences, and "TD" feel is here.

So, I tried your instructions (had to compile first some helloworld.asm from NASM examples to have some test linux binary to run, then you can directly overwrite instructions in debugger for these short questions).

After IMUL eax,ebx the changes to CPU state are:

eax = 0xe0000001
CF = 1, OF = 1, SF = 1, ZF = 0, PF = 0, AF = 0, ...

After IMUL ebx the changes to CPU state are:

eax = 0xe0000001
edx = 0x00ffffff
CF = 1, OF = 1, SF = 1, ZF = 0, PF = 0, AF = 0, ...

(so in this case flags are the same).


I strongly suggest to you to get some nice debugger too, to stop asking questions like these. If it wouldn't be along my own interest to get one debugger running, I wouldn't bother to answer.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • 3
    Be careful of learning how flags work just from a debugger. Many instructions leave some flags "undefined". On any specific CPU, there will usually be a well-defined pattern of behaviour, so you need to read the manual to make sure that what you're seeing sounds like what the manual is describing. (Otherwise you might write code that isn't portable to some other existing x86 CPU, since it depends on implementation-defined behaviour). – Peter Cordes Jun 23 '16 at 11:06
  • 1
    But in this case, I read the manual as saying that CF and OF are set if the upper half of the multiply is non-zero, regardless of whether you used a form that stores the upper half anywhere. – Peter Cordes Jun 23 '16 at 11:07
  • re: debuggers: I think I tried `edb` once, but it was really clunky getting it to use symbol-table information. So it wasn't very convenient when asm-debugging a compiled C program, or even an asm function linked into a C program built with `gcc -g`. Did I miss something? I usually use gdb in a Konsole, with `layout reg` and/or a `display /x $xmm0.v16_int8` or something. It's not great, but mostly works well enough. – Peter Cordes Jun 23 '16 at 11:11
  • 1
    Yeah, obviously the manual is the key point, that's why I put it at first place in the answer. I was just wondering whether IMUL will split CF/OF by sign of result, as humanly -4*5 is not overflow... And I missed completely the size of values in example. Now I tried -4*5, and CF=OF=0. :) – Ped7g Jun 23 '16 at 11:19
  • Oh, right, of course negative results will have non-zero upper halves, and that's why the manual says "significant" rather than "non-zero". Great point. – Peter Cordes Jun 23 '16 at 11:22
  • Regarding `edb`: I don't know, I did want to have some nice debugger for pure ASM (I'm toying around with idea of getting back to doing some demo scene intros), so the symbol table is not bothering me yet, while look and feel and AT&T **is**. Checking it now, that NASM helloworld example has label "msg" for string, it's visible in plugins/symbol viewer, but it's polluted by clib and elf binary init code. In the disassembly window there is raw offset as hex number, no label. So yeah, doesn't look that symbol friendly (although I'm using it like 20min netto, and didn't read any docs). – Ped7g Jun 23 '16 at 11:23
  • 2
    Put `set disassembly-flavor intel` / `layout reg` in your `~/.gdbinit` :) – Peter Cordes Jun 23 '16 at 11:24