Re: clobbered registers




"luke" <spamtrap@xxxxxxxxxx> wrote in message
news:1146140295.876099.121750@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi everybody,
I'm trying to develop a little operating system,
but I can't resolve the following issue.
I have defined a macro which purpose is to set the base address of a
segment:

#define set_base(addr,base) \
__asm__("movw %%dx,%0\n\t" \
"rorl $16,%%edx\n\t" \
"movb %%dl,%1\n\t" \
"movb %%dh,%2" \
::"m" (*((addr)+2)), \
"m" (*((addr)+4)), \
"m" (*((addr)+7)), \
"d" (base) \
)

The problem is that when I use it in the following way:

set_base(ldt[1], code_base);
set_base(ldt[2], data_base);

the gcc compiler doesn't reload the edx register so I get a wrong
result.
The code I get after disassemby is:

6133: 89 f2 mov %esi,%edx

6135: 66 89 93 52 01 00 00 mov %dx,0x152(%ebx)
613c: c1 ca 10 ror $0x10,%edx
613f: 88 93 54 01 00 00 mov %dl,0x154(%ebx)
6145: 88 b3 57 01 00 00 mov %dh,0x157(%ebx)

614b: 66 89 93 5a 01 00 00 mov %dx,0x15a(%ebx)
6152: c1 ca 10 ror $0x10,%edx
6155: 88 93 5c 01 00 00 mov %dl,0x15c(%ebx)
615b: 88 b3 5f 01 00 00 mov %dh,0x15f(%ebx)

as you can notice there is no reload of the register edx between the
two calls.

Some hints I can give you are:

1) I use gcc 3.4.4 with the following options:
-Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions


2) If I put some dummy code between the two calls all is working
correctly. For example:

set_base(ldt[1], code_base);
printk("dummy\n");
set_base(ldt[2], data_base);


3) I have tryed to add edx in the "clobbered registers list" but the
compiler complains about
"Can't find a register in class DREGS"


For DJGPP gcc 3.4.1,

1) -O, -O2, etc. causes the output assembly to switch from %ebx to %eax
2) every combination of options I tried reloaded %eax (or %ebx if
no -O, -O2, etc.)

Since you didn't post some C code, I used the following C snippet (it is
_incorrect_, ldt should be a an array of structures eight 8-bit bytes in
length with a layout matching either the segment or gate descriptors,
code_base and data_base aren't inited etc..etc..and I don't know how you set
them up...) Your GCC options produced the assembly listing following the C
snippet. In all cases, it appeared that the register is reloaded... One
suggestion: If you know C and are using it in this project, it would be much
easier to just use C without the assembly.

---C snippet---

#define set_base(addr,base) \
__asm__("movw %%dx,%0\n\t" \
"rorl $16,%%edx\n\t" \
"movb %%dl,%1\n\t" \
"movb %%dh,%2" \
::"m" (*((addr)+2)), \
"m" (*((addr)+4)), \
"m" (*((addr)+7)), \
"d" (base) \
)

int main(void)
{

unsigned long *ldt[4];
void *code_base, *data_base;

set_base(ldt[1],code_base);
set_base(ldt[2],data_base);

}

---Asm snippet---

.file "lidt.c"
.section .text
..globl _main
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp
subl $16, %esp
movl -20(%ebp), %eax
/APP
movw %dx,8(%eax)
rorl $16,%edx
movb %dl,16(%eax)
movb %dh,28(%eax)
/NO_APP
movl -16(%ebp), %eax
/APP
movw %dx,8(%eax)
rorl $16,%edx
movb %dl,16(%eax)
movb %dh,28(%eax)
/NO_APP
leave
ret
.ident "GCC: (GNU) 3.4.1"


Sorry,

Rod Pemberton





.



Relevant Pages

  • Re: Kind of new: function implementation questions, MASM
    ... >>So, maybe I should not be modifying the ds register, only modifying ... > which has the proper offsets. ... then it is not feasible to use the data segment ... I think I want to not use at all ebp in the function, but only use esp. ...
    (comp.lang.asm.x86)
  • Re: Challenge to evolutionists
    ... a division of a literary work, esp. ... to register or list for a place, transportation, ... to act as a bookmaker for: ... shown by a book of account: The firm's book profit was $53,680. ...
    (talk.origins)
  • Re: Help understanding uops, etc...
    ... > using ECX as my counter instead of EDX sounds intriguing but with my ... They only support using immediates or the cl register. ... You mean esp, and yes, it is faster because you now have another register to ... When you do push/pop items from the stack, ...
    (comp.lang.asm.x86)
  • Re: gcc return reg on inline asm
    ... gcc ended up using eax as ... It was valid code as far as gcc was concerned ... way I know of to tell GCC that the result is in the flags register, ... way to do it, but as you've probably noticed by now, the only register pair ...
    (comp.lang.asm.x86)
  • Re: [klibc 37/43] x86_64 support for klibc
    ... +#undef NSIG ... I can't remove the workaround just yet, since I have active users of the ... were hard-coded in the patterns (using register variables, ... on older gcc versions. ...
    (Linux-Kernel)