-2

I want to know what's the meaning of this function:

void dos_print(char *str)
{
    asm("mov $0x09, %%ah\n"
        "int $0x21\n"
        :
        :"d"(str)
        :"ah");
}
  • 2
    Unlike most people here, you have an excellent chance to ask its author to explain it to you. All jokes aside, you may want to focus the question a bit, explaining all of DOS assembly would be a tad too broad. What is your partial understanding of it and what parts are you unclear on? –  Feb 28 '21 at 18:45
  • This has a bug that could bit you: missing a `"memory"` clobber: your code reads the pointed-to string, but you only tell the compiler that the pointer value itself is an input, not the pointed-to memory. [How can I indicate that the memory \*pointed\* to by an inline ASM argument may be used?](https://stackoverflow.com/q/56432259) – Peter Cordes Mar 01 '21 at 01:30

1 Answers1

1

asm is a GCC extension to C that lets you insert assembly language into the program.

mov $0x09, %%ah\n generates an instruction that moves 9 into the AH register. int $0x21 generates an instruction that is a request to the operating system, passing it the value 0x21. In DOS, an interrupt with value 0x21 and 9 in AH asks the system to print a string. The : line is where you would tell GCC where results of the assembly code are produced. It is empty because this code does not produce any values that the program cares about. The line :"d"(str) tells GCC to put the value of str (a pointer to the first character of the string) in the DX register before executing this assembly code. The :"ah" line tells GCC that the assembly code may change the contents of the AH register.

This Wikipedia page has some information about DOS interrupts.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 2
    I would also add this for reference: http://spike.scu.edu.au/~barry/interrupts.html –  Feb 28 '21 at 18:54
  • Note that it does *not* tell the compiler that the memory pointed-to by `str` is also an input, just the pointer value itself. ([How can I indicate that the memory \*pointed\* to by an inline ASM argument may be used?](https://stackoverflow.com/q/56432259)). For all it knows, the asm is just going to check if the pointer is aligned, not deref it. – Peter Cordes Mar 01 '21 at 01:33
  • Also, since there are no output operands, it's implicitly `volatile`. So it's not assumed to be a pure function of the inputs, with no side effects, like it would be if there was an output. Usually a good idea to make `volatile` explicit, but understanding that it's there implicitly is an important part of understanding why this isn't broken in that respect. – Peter Cordes Mar 01 '21 at 01:33