Re: clobbered registers



Thanks Rod.

As far as I can see your code, as well, is not working correctly:

/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

there is no reloading of register edx. If the edx is not reloaded the
ror instruction of the 1st block does mess it up.

Your GCC options produced the assembly listing following the C
snippet. In all cases, it appeared that the register is reloaded...

which register? I mean edx register not eax


Rod Pemberton wrote:
"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: clobbered registers
    ... as you can notice there is no reload of the register edx between the ... I use gcc 3.4.4 with the following options: ... movl %esp, %ebp ... movb %dl,16 ...
    (comp.lang.asm.x86)
  • [OT] Re: can a character be negative?
    ... it is unwise to target R6 or R7, aka SP and PC, with MOVB). ... (I think I would take issue with DEC for having an instruction that does not do what it says. ... When the target of MOVB is a register ...
    (comp.lang.c)
  • Re: Implementing my own memcpy
    ... it should have been "movb". ... address only the high or low half of each register, ... These had three-letter assembler mnemonics; ... Reading email is like searching for food in the garbage, ...
    (comp.lang.c)
  • Re: can a character be negative?
    ... I'm not so familiar with PDP11, but I think byte values used the lower half of each register, with no auto-extend from 8 to 16 bits, and anyway can work with that lower half independently, effectively giving it byte-wide registers. ... to load a char value into a register that will also sign-extend or clear the top half? ... The opcode is MOVB with a register destination (any of ... it is unwise to target R6 or R7, aka SP and PC, with MOVB). ...
    (comp.lang.c)
  • Re: sio / puc wedging on both -current and -stable (with trace)
    ... Stopped at siointr1+0x148: movl 0x38,%ebx ... Stopped at siointr1+0x17b: movb 0xfffffff7,%dl ... Stopped at siointr1+0x190: jnz siointr1+0x1a7 ... Stopped at siointr1+0x1c3: testb $0x1f,%al ...
    (freebsd-current)