Before we discuss the code itself, I would like to ask that, in the future (and in this case too, if you go back and edit the original post), you use put any formatted code samples between a
[/b] tag pair, like so:
Code: Select all
#define switch_to(n) {
struct {long a,b;} __tmp;
__asm__("cmpl %%ecx,_current\n\t"
"je 1f\n\t"
"xchgl %%ecx,_current\n\t"
"movw %%dx,%1\n\t"
"ljmp %0\n\t"
"cmpl %%ecx,%2\n\t"
"jne 1f\n\t"
"clts\n"
"1:"
::"m" (*&__tmp.a),
"m" (*&__tmp.b),
"m" (last_task_used_math),
"d" _TSS(n),
"c" ((long) task[n]));
}
You can use the 'CODE' button at the top of the editing window to do this automatically.
To address the question, I will point out that
switch_to() is a macro rather than a function. This means that when you invoke
switch_to(), it is not passing
n as a variable on the stack (or in registers, as the case may be), but rather the exact text of the argument is substituted for
n in the compiler text stream. If you wrote
what the pre-processor would generate would be the code snippet
Code: Select all
struct {long a,b;} __tmp;
__asm__("cmpl %%ecx,_current\n\t"
"je 1f\n\t"
"xchgl %%ecx,_current\n\t"
"movw %%dx,%1\n\t"
"ljmp %0\n\t"
"cmpl %%ecx,%2\n\t"
"jne 1f\n\t"
"clts\n"
"1:"
::"m" (*&__tmp.a),
"m" (*&__tmp.b),
"m" (last_task_used_math),
"d" _TSS(n),
"c" ((long) task[2+4]));
I should add that the code as given probably won't work in a modern version of GCC anyway, as it doesn't use line continuations (the backslash,
\) at the end of each line to show that it is all part of a single directive. This may simply be an issue with how the code was pasted in, though.
As for the pointers to
__tmp.a and
__tmp.b, those are passed to the assembler using the inline assembly placeholder
m, which is used to indicate that it is a memory operand holding an address. These become the inline assembly variables
%0 and
%1, respectively.