From 575dc45e34db19ee7808c116e93485b37e0df716 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 20 Dec 2005 00:25:23 +0000 Subject: [PATCH] Revert Intel-style assembly back to AT&T-style. The Intel-style assembly found too many bugs in GAS and the GAS folks actually changed behavior on us for lidt, lgdt. --- doc/userprog.texi | 4 +- src/Make.config | 2 +- src/lib/kernel/bitmap.c | 6 +- src/lib/user/syscall.c | 66 ++++----- src/tests/userprog/child-bad.c | 2 +- src/tests/userprog/sc-bad-arg.c | 2 +- src/tests/userprog/sc-bad-sp.c | 2 +- src/tests/userprog/sc-boundary-2.c | 2 +- src/tests/userprog/sc-boundary.c | 2 +- src/tests/vm/pt-grow-bad.c | 2 +- src/tests/vm/pt-grow-pusha.c | 10 +- src/threads/init.c | 2 +- src/threads/interrupt.c | 4 +- src/threads/io.h | 24 ++-- src/threads/loader.S | 214 ++++++++++++++--------------- src/threads/switch.S | 40 +++--- src/threads/thread.c | 2 +- src/userprog/exception.c | 2 +- src/userprog/pagedir.c | 4 +- src/userprog/process.c | 2 +- 20 files changed, 193 insertions(+), 201 deletions(-) diff --git a/doc/userprog.texi b/doc/userprog.texi index bab70ec..8773209 100644 --- a/doc/userprog.texi +++ b/doc/userprog.texi @@ -415,7 +415,7 @@ provide a little bit of helpful code: Returns true if successful, false if USRC is invalid. */ static inline bool get_user (uint8_t *kdst, const uint8_t *usrc) { int eax; - asm ("mov %%eax, offset 1f; mov %%al, %2; mov %0, %%al; 1:" + asm ("movl $1f, %%eax; movb %2, %%al; movb %%al, %0; 1:" : "=m" (*kdst), "=&a" (eax) : "m" (*usrc)); return eax != 0; } @@ -424,7 +424,7 @@ static inline bool get_user (uint8_t *kdst, const uint8_t *usrc) { Returns true if successful, false if UDST is invalid. */ static inline bool put_user (uint8_t *udst, uint8_t byte) { int eax; - asm ("mov %%eax, offset 1f; mov %0, %b2; 1:" + asm ("movl $1f, %%eax; movb %b2, %0; 1:" : "=m" (*udst), "=&a" (eax) : "r" (byte)); return eax != 0; } diff --git a/src/Make.config b/src/Make.config index 8744f0d..0a1b46a 100644 --- a/src/Make.config +++ b/src/Make.config @@ -21,7 +21,7 @@ endif # Compiler and assembler invocation. DEFINES = WARNINGS = -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wsystem-headers -CFLAGS = -g -MMD -msoft-float -masm=intel +CFLAGS = -g -MMD -msoft-float CPPFLAGS = -nostdinc -I$(SRCDIR) -I- -I$(SRCDIR)/lib ASFLAGS = -Wa,--gstabs -MMD LDFLAGS = diff --git a/src/lib/kernel/bitmap.c b/src/lib/kernel/bitmap.c index df23cc3..d323b89 100644 --- a/src/lib/kernel/bitmap.c +++ b/src/lib/kernel/bitmap.c @@ -163,7 +163,7 @@ bitmap_mark (struct bitmap *b, size_t bit_idx) /* This is equivalent to `b->bits[idx] |= mask' except that it is guaranteed to be atomic on a uniprocessor machine. See the description of the OR instruction in [IA32-v2b]. */ - asm ("or %0, %1" : "=m" (b->bits[idx]) : "r" (mask) : "cc"); + asm ("orl %1, %0" : "=m" (b->bits[idx]) : "r" (mask) : "cc"); } /* Atomically sets the bit numbered BIT_IDX in B to false. */ @@ -176,7 +176,7 @@ bitmap_reset (struct bitmap *b, size_t bit_idx) /* This is equivalent to `b->bits[idx] &= ~mask' except that it is guaranteed to be atomic on a uniprocessor machine. See the description of the AND instruction in [IA32-v2a]. */ - asm ("and %0, %1" : "=m" (b->bits[idx]) : "r" (~mask) : "cc"); + asm ("andl %1, %0" : "=m" (b->bits[idx]) : "r" (~mask) : "cc"); } /* Atomically toggles the bit numbered IDX in B; @@ -191,7 +191,7 @@ bitmap_flip (struct bitmap *b, size_t bit_idx) /* This is equivalent to `b->bits[idx] ^= mask' except that it is guaranteed to be atomic on a uniprocessor machine. See the description of the XOR instruction in [IA32-v2b]. */ - asm ("xor %0, %1" : "=m" (b->bits[idx]) : "r" (mask) : "cc"); + asm ("xorl %1, %0" : "=m" (b->bits[idx]) : "r" (mask) : "cc"); } /* Returns the value of the bit numbered IDX in B. */ diff --git a/src/lib/user/syscall.c b/src/lib/user/syscall.c index 6cc02d1..6fc26ed 100644 --- a/src/lib/user/syscall.c +++ b/src/lib/user/syscall.c @@ -3,45 +3,45 @@ /* Invokes syscall NUMBER, passing no arguments, and returns the return value as an `int'. */ -#define syscall0(NUMBER) \ - ({ \ - int retval; \ - asm volatile \ - ("push %[number]; int 0x30; add %%esp, 4" \ - : "=a" (retval) \ - : [number] "i" (NUMBER) \ - : "memory"); \ - retval; \ +#define syscall0(NUMBER) \ + ({ \ + int retval; \ + asm volatile \ + ("pushl %[number]; int $0x30; addl $4, %%esp" \ + : "=a" (retval) \ + : [number] "i" (NUMBER) \ + : "memory"); \ + retval; \ }) /* Invokes syscall NUMBER, passing argument ARG0, and returns the return value as an `int'. */ -#define syscall1(NUMBER, ARG0) \ - ({ \ - int retval; \ - asm volatile \ - ("push %[arg0]; push %[number]; int 0x30; add %%esp, 8" \ - : "=a" (retval) \ - : [number] "i" (NUMBER), \ - [arg0] "g" (ARG0) \ - : "memory"); \ - retval; \ +#define syscall1(NUMBER, ARG0) \ + ({ \ + int retval; \ + asm volatile \ + ("pushl %[arg0]; pushl %[number]; int $0x30; addl $8, %%esp" \ + : "=a" (retval) \ + : [number] "i" (NUMBER), \ + [arg0] "g" (ARG0) \ + : "memory"); \ + retval; \ }) /* Invokes syscall NUMBER, passing arguments ARG0 and ARG1, and returns the return value as an `int'. */ -#define syscall2(NUMBER, ARG0, ARG1) \ - ({ \ - int retval; \ - asm volatile \ - ("push %[arg1]; push %[arg0]; " \ - "push %[number]; int 0x30; add %%esp, 12" \ - : "=a" (retval) \ - : [number] "i" (NUMBER), \ - [arg0] "g" (ARG0), \ - [arg1] "g" (ARG1) \ - : "memory"); \ - retval; \ +#define syscall2(NUMBER, ARG0, ARG1) \ + ({ \ + int retval; \ + asm volatile \ + ("pushl %[arg1]; pushl %[arg0]; " \ + "pushl %[number]; int $0x30; addl $12, %%esp" \ + : "=a" (retval) \ + : [number] "i" (NUMBER), \ + [arg0] "g" (ARG0), \ + [arg1] "g" (ARG1) \ + : "memory"); \ + retval; \ }) /* Invokes syscall NUMBER, passing arguments ARG0, ARG1, and @@ -50,8 +50,8 @@ ({ \ int retval; \ asm volatile \ - ("push %[arg2]; push %[arg1]; push %[arg0]; " \ - "push %[number]; int 0x30; add %%esp, 16" \ + ("pushl %[arg2]; pushl %[arg1]; pushl %[arg0]; " \ + "pushl %[number]; int $0x30; addl $16, %%esp" \ : "=a" (retval) \ : [number] "i" (NUMBER), \ [arg0] "g" (ARG0), \ diff --git a/src/tests/userprog/child-bad.c b/src/tests/userprog/child-bad.c index 70cfc6a..185617c 100644 --- a/src/tests/userprog/child-bad.c +++ b/src/tests/userprog/child-bad.c @@ -4,6 +4,6 @@ void test_main (void) { - asm volatile ("mov %esp, 0x20101234; int 0x30"); + asm volatile ("movl $0x20101234, %esp; int $0x30"); fail ("should have exited with -1"); } diff --git a/src/tests/userprog/sc-bad-arg.c b/src/tests/userprog/sc-bad-arg.c index 2df966f..b990468 100644 --- a/src/tests/userprog/sc-bad-arg.c +++ b/src/tests/userprog/sc-bad-arg.c @@ -5,7 +5,7 @@ void test_main (void) { - asm volatile ("mov %%esp, 0xbffffffc; mov [dword ptr %%esp], %0; int 0x30" + asm volatile ("movl $0xbffffffc, %%esp; movl %0, (%%esp); int $0x30" :: "i" (SYS_exit)); fail ("should have called exit(-1)"); } diff --git a/src/tests/userprog/sc-bad-sp.c b/src/tests/userprog/sc-bad-sp.c index 8c42298..2ae20e9 100644 --- a/src/tests/userprog/sc-bad-sp.c +++ b/src/tests/userprog/sc-bad-sp.c @@ -4,6 +4,6 @@ void test_main (void) { - asm volatile ("mov %esp, 0x20101234; int 0x30"); + asm volatile ("movl $0x20101234, %esp; int $0x30"); fail ("should have called exit(-1)"); } diff --git a/src/tests/userprog/sc-boundary-2.c b/src/tests/userprog/sc-boundary-2.c index c287d24..47d28c6 100644 --- a/src/tests/userprog/sc-boundary-2.c +++ b/src/tests/userprog/sc-boundary-2.c @@ -13,6 +13,6 @@ test_main (void) p[1] = 67; /* Invoke the system call. */ - asm volatile ("mov %%esp, %0; int 0x30" :: "g" (p)); + asm volatile ("movl %0, %%esp; int $0x30" :: "g" (p)); fail ("should have called exit(67)"); } diff --git a/src/tests/userprog/sc-boundary.c b/src/tests/userprog/sc-boundary.c index 10340b4..86371d6 100644 --- a/src/tests/userprog/sc-boundary.c +++ b/src/tests/userprog/sc-boundary.c @@ -14,6 +14,6 @@ test_main (void) p[1] = 42; /* Invoke the system call. */ - asm volatile ("mov %%esp, %0; int 0x30" :: "g" (p)); + asm volatile ("movl %0, %%esp; int $0x30" :: "g" (p)); fail ("should have called exit(42)"); } diff --git a/src/tests/vm/pt-grow-bad.c b/src/tests/vm/pt-grow-bad.c index 2629574..d83890f 100644 --- a/src/tests/vm/pt-grow-bad.c +++ b/src/tests/vm/pt-grow-bad.c @@ -9,5 +9,5 @@ test_main (void) { /* Read from an address 4,096 bytes below the stack pointer. Must kill the program. */ - asm volatile ("mov %eax, [%esp - 4096]"); + asm volatile ("movl -4096(%esp), %eax"); } diff --git a/src/tests/vm/pt-grow-pusha.c b/src/tests/vm/pt-grow-pusha.c index 61efb01..7596880 100644 --- a/src/tests/vm/pt-grow-pusha.c +++ b/src/tests/vm/pt-grow-pusha.c @@ -8,9 +8,9 @@ void test_main (void) { asm volatile - ("mov %%eax, %%esp;" /* Save a copy of the stack pointer. */ - "and %%esp, 0xfffff000;" /* Move stack pointer to bottom of page. */ - "pusha;" /* Push 32 bytes on stack at once. */ - "mov %%esp, %%eax" /* Restore copied stack pointer. */ - ::: "eax"); /* Tell GCC we modified eax. */ + ("movl %%esp, %%eax;" /* Save a copy of the stack pointer. */ + "andl $0xfffff000, %%esp;" /* Move stack pointer to bottom of page. */ + "pushal;" /* Push 32 bytes on stack at once. */ + "movl %%eax, %%esp" /* Restore copied stack pointer. */ + ::: "eax"); /* Tell GCC we destroyed eax. */ } diff --git a/src/threads/init.c b/src/threads/init.c index 8ee50a2..e2f6379 100644 --- a/src/threads/init.c +++ b/src/threads/init.c @@ -196,7 +196,7 @@ paging_init (void) aka PDBR (page directory base register). This activates our new page tables immediately. See [IA32-v2a] "MOV--Move to/from Control Registers" and [IA32-v3] 3.7.5. */ - asm volatile ("mov %%cr3, %0" :: "r" (vtop (base_page_dir))); + asm volatile ("movl %0, %%cr3" :: "r" (vtop (base_page_dir))); } /* Breaks the kernel command line into words and returns them as diff --git a/src/threads/interrupt.c b/src/threads/interrupt.c index 82b7db7..2b43fd9 100644 --- a/src/threads/interrupt.c +++ b/src/threads/interrupt.c @@ -54,7 +54,7 @@ intr_get_level (void) /* Push the flags register on the processor stack, then pop the value off the stack into `flags'. See [IA32-v2b] "PUSHF" and "POP" and [IA32-v3] 5.8.1. */ - asm volatile ("pushf; pop %0" : "=g" (flags)); + asm volatile ("pushfl; popl %0" : "=g" (flags)); return flags & FLAG_IF ? INTR_ON : INTR_OFF; } @@ -380,7 +380,7 @@ intr_dump_frame (const struct intr_frame *f) See [IA32-v2a] "MOV--Move to/from Control Registers" and [IA32-v3] 5.14 "Interrupt 14--Page Fault Exception (#PF)". */ - asm ("mov %0, %%cr2" : "=r" (cr2)); + asm ("movl %%cr2, %0" : "=r" (cr2)); printf ("Interrupt %#04x (%s) at eip=%p\n", f->vec_no, intr_names[f->vec_no], f->eip); diff --git a/src/threads/io.h b/src/threads/io.h index cf9eee0..b493299 100644 --- a/src/threads/io.h +++ b/src/threads/io.h @@ -50,7 +50,7 @@ inb (uint16_t port) { /* See [IA32-v2a] "IN". */ uint8_t data; - asm volatile ("inb %0, %w1" : "=a" (data) : "d" (port)); + asm volatile ("inb %w1,%0" : "=a" (data) : "d" (port)); return data; } @@ -60,7 +60,7 @@ static inline void insb (uint16_t port, void *addr, size_t cnt) { /* See [IA32-v2a] "INS". */ - asm volatile ("cld; repne insb" + asm volatile ("cld; repne; insb" : "=D" (addr), "=c" (cnt) : "d" (port), "0" (addr), "1" (cnt) : "memory", "cc"); @@ -72,7 +72,7 @@ inw (uint16_t port) { uint16_t data; /* See [IA32-v2a] "IN". */ - asm volatile ("inw %0, %w1" : "=a" (data) : "d" (port)); + asm volatile ("inw %w1,%0" : "=a" (data) : "d" (port)); return data; } @@ -82,7 +82,7 @@ static inline void insw (uint16_t port, void *addr, size_t cnt) { /* See [IA32-v2a] "INS". */ - asm volatile ("cld; repne insw" + asm volatile ("cld; repne; insw" : "=D" (addr), "=c" (cnt) : "d" (port), "0" (addr), "1" (cnt) : "memory", "cc"); @@ -94,7 +94,7 @@ inl (uint16_t port) { /* See [IA32-v2a] "IN". */ uint32_t data; - asm volatile ("ind %0, %w1" : "=a" (data) : "d" (port)); + asm volatile ("inl %w1,%0" : "=a" (data) : "d" (port)); return data; } @@ -104,7 +104,7 @@ static inline void insl (uint16_t port, void *addr, size_t cnt) { /* See [IA32-v2a] "INS". */ - asm volatile ("cld; repne insd" + asm volatile ("cld; repne; insl" : "=D" (addr), "=c" (cnt) : "d" (port), "0" (addr), "1" (cnt) : "memory", "cc"); @@ -115,7 +115,7 @@ static inline void outb (uint16_t port, uint8_t data) { /* See [IA32-v2b] "OUT". */ - asm volatile ("outb %w1, %0" : : "a" (data), "d" (port)); + asm volatile ("outb %0,%w1" : : "a" (data), "d" (port)); } /* Writes to PORT each byte of data in the CNT-byte buffer @@ -124,7 +124,7 @@ static inline void outsb (uint16_t port, const void *addr, size_t cnt) { /* See [IA32-v2b] "OUTS". */ - asm volatile ("cld; repne outsb" + asm volatile ("cld; repne; outsb" : "=S" (addr), "=c" (cnt) : "d" (port), "0" (addr), "1" (cnt) : "cc"); @@ -135,7 +135,7 @@ static inline void outw (uint16_t port, uint16_t data) { /* See [IA32-v2b] "OUT". */ - asm volatile ("outw %w1, %0" : : "a" (data), "d" (port)); + asm volatile ("outw %0,%w1" : : "a" (data), "d" (port)); } /* Writes to PORT each 16-bit unit (halfword) of data in the @@ -144,7 +144,7 @@ static inline void outsw (uint16_t port, const void *addr, size_t cnt) { /* See [IA32-v2b] "OUTS". */ - asm volatile ("cld; repne outsw" + asm volatile ("cld; repne; outsw" : "=S" (addr), "=c" (cnt) : "d" (port), "0" (addr), "1" (cnt) : "cc"); @@ -155,7 +155,7 @@ static inline void outl (uint16_t port, uint32_t data) { /* See [IA32-v2b] "OUT". */ - asm volatile ("outd %w1, %0" : : "a" (data), "d" (port)); + asm volatile ("outl %0,%w1" : : "a" (data), "d" (port)); } /* Writes to PORT each 32-bit unit (word) of data in the CNT-word @@ -164,7 +164,7 @@ static inline void outsl (uint16_t port, const void *addr, size_t cnt) { /* See [IA32-v2b] "OUTS". */ - asm volatile ("cld; repne outsd" + asm volatile ("cld; repne; outsl" : "=S" (addr), "=c" (cnt) : "d" (port), "0" (addr), "1" (cnt) : "cc"); diff --git a/src/threads/loader.S b/src/threads/loader.S index 796dca8..fc834ff 100644 --- a/src/threads/loader.S +++ b/src/threads/loader.S @@ -40,8 +40,6 @@ #include "threads/loader.h" - .intel_syntax noprefix - #### Kernel loader. #### This code should be stored in the first sector of the hard disk. @@ -72,17 +70,17 @@ start: # Set up data segments. - sub ax, ax - mov es, ax - mov ds, ax + subw %ax, %ax + movw %ax, %es + movw %ax, %ds # Set up stack segment. # Stack grows downward starting from us. -# We don't ever use the stack so this is strictly speaking -# unnecessary. +# We don't ever use the stack, but we call into the BIOS, +# which might. - mov ss, ax - mov sp, 0x7c00 + movw %ax, %ss + movw $0x7c00, %sp #### Enable A20. Address line 20 is tied to low when the machine #### boots, which prevents addressing memory about 1 MB. This code @@ -90,94 +88,90 @@ start: # Poll status register while busy. -1: in al, 0x64 - test al, 0x2 +1: inb $0x64, %al + testb $0x2, %al jnz 1b # Send command for writing output port. - mov al, 0xd1 - outb 0x64, al + movb $0xd1, %al + outb %al, $0x64 # Poll status register while busy. -1: in al, 0x64 - test al, 0x2 +1: inb $0x64, %al + testb $0x2, %al jnz 1b # Enable A20 line. - mov al, 0xdf - out 0x60, al + movb $0xdf, %al + outb %al, $0x60 -#### Get memory size, via interrupt 15h function 88h, which returns CF +#### Get memory size, via interrupt 15h function 88h. Returns CF #### clear if successful, with AX = (kB of physical memory) - 1024. #### This only works for memory sizes <= 65 MB, which should be fine #### for our purposes. We cap memory at 64 MB because that's all we #### prepare page tables for, below. - mov ah, 0x88 - int 0x15 + movb $0x88, %ah + int $0x15 jc panic cli # BIOS might have enabled interrupts - add eax, 1024 # Total kB memory - cmp eax, 0x10000 # Cap at 64 MB + addl $1024, %eax # Total kB memory + cmp $0x10000, %eax # Cap at 64 MB jbe 1f - mov eax, 0x10000 -1: shr eax, 2 # Total 4 kB pages - mov ram_pgs, eax + mov $0x10000, %eax +1: shrl $2, %eax # Total 4 kB pages + movl %eax, ram_pgs #### Create temporary page directory and page table and set page #### directory base register. # Create page directory at 64 kB and fill with zeroes. - mov ax, 0x1000 - mov es, ax - sub eax, eax - sub edi, edi - mov ecx, 0x400 - rep stosd + mov $0x1000, %ax + mov %ax, %es + subl %eax, %eax + subl %edi, %edi + movl $0x400, %ecx + rep stosl # Add PDEs to point to PTEs for the first 64 MB of RAM. # Also add identical PDEs starting at LOADER_PHYS_BASE. -# See [IA32-v3] section 3.7.6 for a description of the bits in eax. - -# A bug in some versions of GAS prevents us from using the straightforward -# mov es:[di + LOADER_PHYS_BASE / 1024 / 1024], eax -# so we calculate the displacement in bx instead. - - mov eax, 0x11007 - mov ecx, 0x11 - sub di, di - mov ebx, LOADER_PHYS_BASE - shr ebx, 20 -1: mov es:[di], eax - mov es:[bx + di], eax - add di, 4 - add eax, 0x1000 +# See [IA32-v3] section 3.7.6 for a description of the bits in %eax. + + movl $0x11007, %eax + movl $0x11, %ecx + subl %edi, %edi +1: movl %eax, %es:(%di) + movl %eax, %es:LOADER_PHYS_BASE >> 20(%di) + addw $4, %di + addl $0x1000, %eax loop 1b # Set up one-to-map linear to physical map for the first 64 MB of RAM. -# See [IA32-v3] section 3.7.6 for a description of the bits in eax. - - mov ax, 0x1100 - mov es, ax - mov eax, 0x7 - mov cx, 0x4000 - sub di, di -1: mov es:[di], eax - add di, 4 - add eax, 0x1000 +# See [IA32-v3] section 3.7.6 for a description of the bits in %eax. + + movw $0x1100, %ax + movw %ax, %es + movl $0x7, %eax + movl $0x4000, %ecx + subl %edi, %edi +1: movl %eax, %es:(%di) + addw $4, %di + addl $0x1000, %eax loop 1b # Set page directory base register. - mov eax, 0x10000 - mov cr3, eax + movl $0x10000, %eax + movl %eax, %cr3 #### Switch to protected mode. -# Then we point the GDTR to our GDT. Protected mode requires a GDT. +# Note that interrupts are still off. + +# Point the GDTR to our GDT. Protected mode requires a GDT. # We need a data32 prefix to ensure that all 32 bits of the GDT # descriptor are loaded (default is to load only 24 bits). @@ -191,18 +185,18 @@ start: # EM (Emulation): forces floating-point instructions to trap. # We don't support floating point. - mov eax, cr0 - or eax, CR0_PE + CR0_PG + CR0_WP + CR0_EM - mov cr0, eax + movl %cr0, %eax + orl $CR0_PE | CR0_PG | CR0_WP | CR0_EM, %eax + movl %eax, %cr0 # We're now in protected mode in a 16-bit segment. The CPU still has -# the real-mode code segment cached in cs's segment descriptor. We -# need to reload cs, and the easiest way is to use a far jump. +# the real-mode code segment cached in %cs's segment descriptor. We +# need to reload %cs, and the easiest way is to use a far jump. # Because we're not in a 32-bit segment the data32 prefix is needed to # jump to a 32-bit offset. - data32 ljmp SEL_KCSEG, 1f + LOADER_PHYS_BASE - + data32 ljmp $SEL_KCSEG, $1f + LOADER_PHYS_BASE + # We're now in protected mode in a 32-bit segment. .code32 @@ -210,83 +204,83 @@ start: # Reload all the other segment registers and the stack pointer to # point into our new GDT. -1: mov ax, SEL_KDSEG - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - mov esp, LOADER_PHYS_BASE + 0x30000 +1: movw $SEL_KDSEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + movl $LOADER_PHYS_BASE + 0x30000, %esp #### Load kernel starting at physical address LOADER_KERN_BASE by #### frobbing the IDE controller directly. - mov ebx, 1 - mov edi, LOADER_KERN_BASE + LOADER_PHYS_BASE + movl $1, %ebx + movl $LOADER_KERN_BASE + LOADER_PHYS_BASE, %edi read_sector: # Poll status register while controller busy. - mov edx, 0x1f7 -1: in al, dx - test al, 0x80 + movl $0x1f7, %edx +1: inb %dx, %al + testb $0x80, %al jnz 1b # Read a single sector. - mov edx, 0x1f2 - mov al, 1 - out dx, al + movl $0x1f2, %edx + movb $1, %al + outb %al, %dx # Sector number to write in low 28 bits. # LBA mode, device 0 in top 4 bits. - mov eax, ebx - and eax, 0x0fffffff - or eax, 0xe0000000 + movl %ebx, %eax + andl $0x0fffffff, %eax + orl $0xe0000000, %eax -# Dump eax to ports 0x1f3...0x1f6. +# Dump %eax to ports 0x1f3...0x1f6. - mov ecx, 4 -1: inc dx - out dx, al - shr eax, 8 + movl $4, %ecx +1: incw %dx + outb %al, %dx + shrl $8, %eax loop 1b # READ command to command register. - inc dx - mov al, 0x20 - out dx, al + incw %dx + movb $0x20, %al + outb %al, %dx # Poll status register while controller busy. -1: in al, dx - test al, 0x80 +1: inb %dx, %al + testb $0x80, %al jnz 1b # Poll status register until data ready. -1: in al, dx - test al, 0x08 +1: inb %dx, %al + testb $0x08, %al jz 1b # Transfer sector. - mov ecx, 256 - mov edx, 0x1f0 + movl $256, %ecx + movl $0x1f0, %edx rep insw # Next sector. - inc ebx - cmp ebx, KERNEL_LOAD_PAGES*8 + 1 + incl %ebx + cmpl $KERNEL_LOAD_PAGES*8 + 1, %ebx jnz read_sector #### Jump to kernel entry point. - mov eax, LOADER_PHYS_BASE + LOADER_KERN_BASE - call eax + movl $LOADER_PHYS_BASE + LOADER_KERN_BASE, %eax + call *%eax jmp panic #### GDT @@ -301,16 +295,16 @@ gdtdesc: .long gdt + LOADER_PHYS_BASE # address gdt #### Fatal error. -#### Print panicmsg (with help from the BIOS) and spin. +#### Print panic_message (with help from the BIOS) and spin. panic: .code16 # We only panic in real mode. - mov si, offset panic_message - mov ah, 0xe - sub bh, bh + movw $panic_message, %si + movb $0xe, %ah + subb %bh, %bh 1: lodsb - test al, al + test %al, %al 2: jz 2b # Spin. - int 0x10 + int $0x10 jmp 1b panic_message: @@ -327,10 +321,10 @@ ram_pgs: #### This is written by the `pintos' utility and read by the kernel. #### The loader itself does not do anything with the command line. .org LOADER_ARG_CNT - LOADER_BASE -arg_cnt: +arg_cnt: .long 0 .org LOADER_ARGS - LOADER_BASE -args: +args: .fill 0x80, 1, 0 #### Boot-sector signature. diff --git a/src/threads/switch.S b/src/threads/switch.S index f58c4a8..6cb70aa 100644 --- a/src/threads/switch.S +++ b/src/threads/switch.S @@ -12,43 +12,41 @@ #### restore the registers. As part of switching stacks we record the #### current stack pointer in CUR's thread structure. -.intel_syntax noprefix - .globl switch_threads .func switch_threads switch_threads: # Save caller's register state. # - # Note that the SVR4 ABI allows us to destroy eax, ecx, edx, - # but requires us to preserve ebx, ebp, esi, edi. See + # Note that the SVR4 ABI allows us to destroy %eax, %ecx, %edx, + # but requires us to preserve %ebx, %ebp, %esi, %edi. See # [SysV-ABI-386] pages 3-11 and 3-12 for details. # # This stack frame must match the one set up by thread_create(). - push ebx - push ebp - push esi - push edi + pushl %ebx + pushl %ebp + pushl %esi + pushl %edi # Get offsetof (struct thread, stack). .globl thread_stack_ofs - mov edx, thread_stack_ofs + mov thread_stack_ofs, %edx # Save current stack pointer to old thread's stack, if any. - mov eax, SWITCH_CUR[esp] - test eax, eax + movl SWITCH_CUR(%esp), %eax + test %eax, %eax jz 1f - mov [eax + edx], esp + movl %esp, (%eax,%edx,1) 1: # Restore stack pointer from new thread's stack. - mov ecx, SWITCH_NEXT[esp] - mov esp, [ecx + edx] + movl SWITCH_NEXT(%esp), %ecx + movl (%ecx,%edx,1), %esp # Restore caller's register state. - pop edi - pop esi - pop ebp - pop ebx + popl %edi + popl %esi + popl %ebp + popl %ebx ret .endfunc @@ -56,13 +54,13 @@ switch_threads: .func switch_entry switch_entry: # Discard switch_threads() arguments. - add esp, 8 + addl $8, %esp # Call schedule_tail(prev). - push eax + pushl %eax .globl schedule_tail call schedule_tail - add esp, 4 + addl $4, %esp # Start thread proper. ret diff --git a/src/threads/thread.c b/src/threads/thread.c index 7a5c726..dc23efb 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -376,7 +376,7 @@ running_thread (void) down to the start of a page. Because `struct thread' is always at the beginning of a page and the stack pointer is somewhere in the middle, this locates the curent thread. */ - asm ("mov %0, %%esp" : "=g" (esp)); + asm ("mov %%esp, %0" : "=g" (esp)); return pg_round_down (esp); } diff --git a/src/userprog/exception.c b/src/userprog/exception.c index 9a4eb90..d4e02b9 100644 --- a/src/userprog/exception.c +++ b/src/userprog/exception.c @@ -139,7 +139,7 @@ page_fault (struct intr_frame *f) See [IA32-v2a] "MOV--Move to/from Control Registers" and [IA32-v3] 5.14 "Interrupt 14--Page Fault Exception (#PF)". */ - asm ("mov %0, %%cr2" : "=r" (fault_addr)); + asm ("movl %%cr2, %0" : "=r" (fault_addr)); /* Turn interrupts back on (they were only off so that we could be assured of reading CR2 before it changed). */ diff --git a/src/userprog/pagedir.c b/src/userprog/pagedir.c index 4604ca2..9b2e3c0 100644 --- a/src/userprog/pagedir.c +++ b/src/userprog/pagedir.c @@ -223,7 +223,7 @@ pagedir_activate (uint32_t *pd) aka PDBR (page directory base register). This activates our new page tables immediately. See [IA32-v2a] "MOV--Move to/from Control Registers" and [IA32-v3] 3.7.5. */ - asm volatile ("mov %%cr3, %0" :: "r" (vtop (pd))); + asm volatile ("movl %0, %%cr3" :: "r" (vtop (pd))); } /* Returns the currently active page directory. */ @@ -235,7 +235,7 @@ active_pd (void) See [IA32-v2a] "MOV--Move to/from Control Registers" and [IA32-v3] 3.7.5. */ uintptr_t pd; - asm volatile ("mov %0, %%cr3" : "=r" (pd)); + asm volatile ("movl %%cr3, %0" : "=r" (pd)); return ptov (pd); } diff --git a/src/userprog/process.c b/src/userprog/process.c index 58e81fd..6150a06 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -71,7 +71,7 @@ execute_thread (void *filename_) arguments on the stack in the form of a `struct intr_frame', we just point the stack pointer (%esp) to our stack frame and jump to it. */ - asm ("mov %%esp, %0; jmp intr_exit" :: "g" (&if_)); + asm ("movl %0, %%esp; jmp intr_exit" :: "g" (&if_)); NOT_REACHED (); } -- 2.30.2