The ds:
was added by IDA, not by the compiler. If you look at the raw opcode bytes, you will see that there is no DS override prefix in the instruction. It's silly that it does this.
IDA adds that ds:
prefix because otherwise you wouldn't know that this is an indirect call--that is, that it's reading a 32-bit variable at an address named __imp__printf
then calling the address stored in that variable. Without the ds:
, it would be just be calling __imp__printf
directly.
If IDA used a better assembly language syntax--namely, the nasm syntax--that instruction would look like simply this, using brackets to show that it is a memory read (and dword
to distinguish from a few other weird types of call
):
.text:00411279 call dword [__imp__printf]
Windows, like pretty much every other 32-bit OS, has a flat address space. CS, DS, ES and SS all have the same base address, 0, so it doesn't matter which segment you use as your base. (Except that you can't do a memory write if CS is your segment.) FS and GS have different bases, since the major OS's all use them for thread-local storage, but those will always have explicit prefix bytes in the instruction.