1
7c6f:   ec   in     (%dx),%al

Here my doubt is due to ()

Many places I wrote code this worked as take the value inside (%dx) and use it as memory location and value located there is value needed.

But here it should be doing just in %dx,%al ; and %dx hold port no Just like in 0x000,al

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
OSdev
  • 107
  • 6

2 Answers2

2

in %dx, %al assembles to the same 0xEC byte of machine code, which objdump -d disassembles to in (%dx),%al as you've found.

llvm-objdump -d does use the syntax you expected: inb %dx, %al ; inb $128, %al

AT&T syntax's use of (%dx) for the IO port number in in / out is misleading since it's not a normal addressing mode; DX being the only option. Presumably the designers of AT&T syntax wanted to represent the fact that you're reading or writing I/O address space. But they did a bad job because it's inconsistent with their use of in $0x80, %al for immediate port numbers (as opposed to 0x80 for the port number using the same syntax as an absolute memory address). GAS and LLVM don't even accept in 0x80, %al, so no, not "Just like in 0x000,al".

The in / out instructions access IO space, not memory address space.
The "addresses" in IO space are called port numbers.
IO space is still a thing in modern PCI-express, but most modern devices only have MMIO registers in device memory regions, not IO ports, because IO ports are slower to access.


objdump -drwC -Mintel disassembles to the same syntax Intel uses in their manual entry for the only form of in that has a port in DX and byte operand-size. Note the lack of [dx] brackets.

   0:   ec                      in     al,dx
   1:   e4 80                   in     al,0x80

(%dx) is not one of the valid 16-bit addressing modes, so that specific addressing mode is never valid for any other instruction. But yes, (%reg) such as (%edx) or (%bx) is AT&T addressing-mode syntax for memory operands in instructions which allow a normal reg/mem operand such as mov or add.

See also Why there is no parentheses wrapping around AL register?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
0

Your question is quite unclear, but I'll do my best to answer.

Using (%dx) as the first operand doesn’t work the way you think it does; for in and out,
(%dx) is not a memory operand, unlike how the same syntax is used for operands to other instructions.

The IN instruction takes two operands:

  1. An immediate 8-bit value (like $0x42) or the DX register.

  2. AL, AX, or EAX.

This means you cannot use a memory location for either operand.

Also, as seen in @PeterCordes’s answer, using %dx as a memory address is never valid.

For these two reasons, (%dx) cannot be interpreted as a memory address, so your assembler instead ignores the parentheses and interprets it as the register %dx alone.

That means in (%dx),%al is exactly the same as in %dx,%al.

If you want to take input from a port number stored in memory, you must first load the value into the %dx register:

mov (%something),%dx
in %dx,%al

For more information, consult page 3-494 in Volume 2A of the Intel IA-32 reference manual, or this reference page.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
tjcaul
  • 383
  • 1
  • 9
  • 1
    In AT&T syntax, `in (%dx), %al` is valid syntax for the same instruction as `in %dx, %al`. In fact `objdump -d` prefers the first form; that code block in the question is real disassembly. And yes this is insane and wrong looking. Not the only bad / random decision the designers of AT&T syntax made (e.g. strange far-call / far-jmp `ljmp` syntax, although that's actually not crazy IIRC if you look at it the right way), not to mention the actual bugs in early AT&T unix assemblers which are now baked in to the syntax: https://sourceware.org/binutils/docs/as/i386_002dBugs.html – Peter Cordes Feb 24 '22 at 08:50
  • @PeterCordes Thanks for the correction. I mis-interpreted the question to mean that `in (%dx),%al` wasn’t working / assembling. – tjcaul Feb 24 '22 at 15:54
  • 1
    Yeah, it was not a clear question; I only figured out what it meant from having some memory of `(%dx)` showing up in AT&T syntax disassembly, and checking by trying it myself. – Peter Cordes Feb 24 '22 at 21:41