0

I am writing my own OS that have its own printf function. In this function I successfully implemented %d, %u, %x, %c and %s parameters, but for some reason analogical (to %d, u, x) code for %p causes invalid opcode exception which means it's either gasm error or UB.

Here's the code:

} else if (*format == 'p') {
            format++;
            void *p = va_arg(parameters, void*);   <-- invalid opcode exception triggers in this
            long n = (long) p;                         line of code (I know from GDB)
            char buf[64] = "0x";
            itoa64(n, &buf[2], 16);
            size_t len = strlen(buf);
            tty_puts(buf);
            written += len;
} else {

And here's instruction, saved instruction pointer pointed to:

0x202ee2 <printf+866>:  pxor   %xmm0,%xmm0
yomol777
  • 463
  • 4
  • 16
  • 2
    What target architecture did you compile for? What processor did you execute on? If you built for an architecture containing instructions the processor does not have, GCC may have generated instructions your processor does not have. – Eric Postpischil Apr 16 '21 at 17:51
  • I compile my project using x86_64 cross compiler (x86_64-elf-gcc) and run it in qemu-system-x86_64. – yomol777 Apr 16 '21 at 18:00
  • QEMU can emulate various processors or model features. You may need either to configure it for something that supports the `pxor` instruction or to tell GCC to generate code for the processor you are emulating, using [the `-march` switch or the numerous switches to turn instruction subsets on or off](https://gcc.gnu.org/onlinedocs/gcc-10.3.0/gcc/x86-Options.html#x86-Options). I think you need SSE2 for that particular instruction, so `-mno-sse2` would tell GCC to turn that subset off, but you might need to turn others off too. – Eric Postpischil Apr 16 '21 at 18:16
  • `pxor %xmm0,%xmm0` clears register `xmm0` AFAIK, which is the equivalent to `xmm0 = 0;` in C. Are you sure this instruction is in the C code you show? Please generate a disassembly, or let the debugger give you some more context, and post relevant excerpts. – the busybee Apr 16 '21 at 18:55
  • 2
    You're writing your own OS so it's up to you to flip the control-register bits that tell the CPU to let SSE instructions run without faulting. (i.e. your OS promises to save/restore XMM state on context switches; this is how Intel designed things to prevent data corruption from user-space using SSE on OSes that weren't aware of the new architectural state when SSE was new.) – Peter Cordes Apr 16 '21 at 21:45
  • Note that SSE2 is a baseline part of x86-64, but you *could* stop your compiler from using it with `-mno-sse -mno-mmx`. (Like Linux does for kernel code.) – Peter Cordes Apr 16 '21 at 21:46
  • I had to enable SSE for this instruction to work (https://wiki.osdev.org/SSE#Adding_support). – yomol777 Apr 17 '21 at 10:05

0 Answers0