commit 0ee33aaa97ce8231cd322b1cb9a44ac0c937e7ad Author: iDunnoDev Date: Tue Dec 6 11:49:47 2022 +0000 Initial Upload diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..081a43c --- /dev/null +++ b/.cvsignore @@ -0,0 +1,16 @@ +*.asm +*.d +*.sym +_* +kernel +user1 +userfs +usertests +xv6.img +vectors.S +bochsout.txt +bootblock +bootother +bootother.out +parport.out +fmt diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..da72247 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,4 @@ +((c-mode + (indent-tabs-mode . nil) + (c-file-style . "bsd") + (c-basic-offset . 2))) diff --git a/.gdbinit.tmpl b/.gdbinit.tmpl new file mode 100644 index 0000000..f71681a --- /dev/null +++ b/.gdbinit.tmpl @@ -0,0 +1,27 @@ +set $lastcs = -1 + +define hook-stop + # There doesn't seem to be a good way to detect if we're in 16- or + # 32-bit mode, but in 32-bit mode we always run with CS == 8 in the + # kernel and CS == 35 in user space + if $cs == 8 || $cs == 35 + if $lastcs != 8 && $lastcs != 35 + set architecture i386 + end + x/i $pc + else + if $lastcs == -1 || $lastcs == 8 || $lastcs == 35 + set architecture i8086 + end + # Translate the segment:offset into a physical address + printf "[%4x:%4x] ", $cs, $eip + x/i $cs*16+$eip + end + set $lastcs = $cs +end + +echo + target remote localhost:1234\n +target remote localhost:1234 + +echo + symbol-file kernel\n +symbol-file kernel diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5713ac7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.img filter=lfs diff=lfs merge=lfs -text diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..8653e61 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/kernel", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "miDebuggerPath": "/usr/bin/gdb" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..1471a31 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,35 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build Xv6 operating system", + "type": "shell", + "command": "make", + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Run Xv6 under QEMU", + "type": "shell", + "command": "make qemu", + "problemMatcher": [] + }, + { + "label": "Run Xv6 under QEMU for debugging", + "type": "shell", + "command": "make qemu-gdb", + "problemMatcher": [] + }, + { + "label": "Clean non-source files", + "type": "shell", + "command": "make clean", + "problemMatcher": [] + } +] +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..422c0cc --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +The xv6 software is: + +Copyright (c) 2006-2018 Frans Kaashoek, Robert Morris, Russ Cox, + Massachusetts Institute of Technology + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..505c640 --- /dev/null +++ b/Makefile @@ -0,0 +1,250 @@ +OBJS = \ + bio.o\ + console.o\ + exec.o\ + file.o\ + fs.o\ + ide.o\ + ioapic.o\ + kalloc.o\ + kbd.o\ + lapic.o\ + log.o\ + main.o\ + mp.o\ + picirq.o\ + pipe.o\ + proc.o\ + sleeplock.o\ + spinlock.o\ + string.o\ + swtch.o\ + syscall.o\ + sysfile.o\ + sysproc.o\ + trapasm.o\ + trap.o\ + uart.o\ + vectors.o\ + vm.o\ + +# Cross-compiling (e.g., on Mac OS X) +# TOOLPREFIX = i386-jos-elf + +# Using native tools (e.g., on X86 Linux) +#TOOLPREFIX = + +# Try to infer the correct TOOLPREFIX if not set +ifndef TOOLPREFIX +TOOLPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \ + then echo 'i386-jos-elf-'; \ + elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \ + then echo ''; \ + else echo "***" 1>&2; \ + echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \ + echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \ + echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \ + echo "*** prefix other than 'i386-jos-elf-', set your TOOLPREFIX" 1>&2; \ + echo "*** environment variable to that prefix and run 'make' again." 1>&2; \ + echo "*** To turn off this error, run 'gmake TOOLPREFIX= ...'." 1>&2; \ + echo "***" 1>&2; exit 1; fi) +endif + +# If the makefile can't find QEMU, specify its path here +# QEMU = qemu-system-i386 + +# Try to infer the correct QEMU +ifndef QEMU +QEMU = $(shell if which qemu > /dev/null; \ + then echo qemu; exit; \ + elif which qemu-system-i386 > /dev/null; \ + then echo qemu-system-i386; exit; \ + elif which qemu-system-x86_64 > /dev/null; \ + then echo qemu-system-x86_64; exit; \ + else \ + qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu; \ + if test -x $$qemu; then echo $$qemu; exit; fi; fi; \ + echo "***" 1>&2; \ + echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \ + echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \ + echo "*** or have you tried setting the QEMU variable in Makefile?" 1>&2; \ + echo "***" 1>&2; exit 1) +endif + +CC = $(TOOLPREFIX)gcc +AS = $(TOOLPREFIX)gas +LD = $(TOOLPREFIX)ld +OBJCOPY = $(TOOLPREFIX)objcopy +OBJDUMP = $(TOOLPREFIX)objdump +CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer +CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) +ASFLAGS = -m32 -gdwarf-2 -Wa,-divide +# FreeBSD ld wants ``elf_i386_fbsd'' +LDFLAGS += -m $(shell $(LD) -V | grep elf_i386 2>/dev/null | head -n 1) + +# Disable PIE when possible (for Ubuntu 16.10 toolchain) +ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),) +CFLAGS += -fno-pie -no-pie +endif +ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]nopie'),) +CFLAGS += -fno-pie -nopie +endif + +xv6.img: bootblock kernel + dd if=/dev/zero of=xv6.img count=10000 + dd if=bootblock of=xv6.img conv=notrunc + dd if=kernel of=xv6.img seek=1 conv=notrunc + +xv6memfs.img: bootblock kernelmemfs + dd if=/dev/zero of=xv6memfs.img count=10000 + dd if=bootblock of=xv6memfs.img conv=notrunc + dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc + +bootblock: bootasm.S bootmain.c + $(CC) $(CFLAGS) -fno-pic -O -nostdinc -I. -c bootmain.c + $(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootasm.S + $(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o + $(OBJDUMP) -S bootblock.o > bootblock.asm + $(OBJCOPY) -S -O binary -j .text bootblock.o bootblock + # The following line is here since it has been noticed that if you use Explorer to + # copy folders on wsl, sometimees the execute permissions can be removed from perl scripts. + # Uncomment if needed, but it will flag as a change for git. + # chmod +x sign.pl + ./sign.pl bootblock + +syscall.h: gensyscalls.pl + ./gensyscalls.pl -h > syscall.h + +syscalltable.h: gensyscalls.pl + ./gensyscalls.pl -c > syscalltable.h + +usys.S: gensyscalls.pl + ./gensyscalls.pl -a > usys.S + +entryother: entryother.S + $(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c entryother.S + $(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o + $(OBJCOPY) -S -O binary -j .text bootblockother.o entryother + $(OBJDUMP) -S bootblockother.o > entryother.asm + +initcode: initcode.S + $(CC) $(CFLAGS) -nostdinc -I. -c initcode.S + $(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o + $(OBJCOPY) -S -O binary initcode.out initcode + $(OBJDUMP) -S initcode.o > initcode.asm + +kernel: syscall.h syscalltable.h $(OBJS) entry.o entryother initcode kernel.ld + $(LD) $(LDFLAGS) -T kernel.ld -o kernel entry.o $(OBJS) -b binary initcode entryother + $(OBJDUMP) -S kernel > kernel.asm + $(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym + +# kernelmemfs is a copy of kernel that maintains the +# disk image in memory instead of writing to a disk. +# This is not so useful for testing persistent storage or +# exploring disk buffering implementations, but it is +# great for testing the kernel on real hardware without +# needing a scratch disk. +MEMFSOBJS = $(filter-out ide.o,$(OBJS)) memide.o +kernelmemfs: $(MEMFSOBJS) entry.o entryother initcode kernel.ld fs.img + $(LD) $(LDFLAGS) -T kernel.ld -o kernelmemfs entry.o $(MEMFSOBJS) -b binary initcode entryother fs.img + $(OBJDUMP) -S kernelmemfs > kernelmemfs.asm + $(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym + +tags: $(OBJS) entryother.S _init + etags *.S *.c + +vectors.S: vectors.pl + # chmod +x vectors.pl + ./vectors.pl > vectors.S + +ULIB = ulib.o usys.o printf.o umalloc.o + +_%: %.o $(ULIB) + $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^ + $(OBJDUMP) -S $@ > $*.asm + $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym + +_forktest: forktest.o $(ULIB) + # forktest has less library code linked in - needs to be small + # in order to be able to max out the proc table. + $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o + $(OBJDUMP) -S _forktest > forktest.asm + +mkfs: mkfs.c fs.h + gcc -Werror -Wall -o mkfs mkfs.c + +# Prevent deletion of intermediate files, e.g. cat.o, after first build, so +# that disk image changes after first build are persistent until clean. More +# details: +# http://www.gnu.org/software/make/manual/html_node/Chained-Rules.html +.PRECIOUS: %.o + +UPROGS=\ + _cat\ + _echo\ + _forktest\ + _grep\ + _init\ + _kill\ + _ln\ + _ls\ + _mkdir\ + _rm\ + _sh\ + _stressfs\ + _usertests\ + _wc\ + _zombie\ + _hello\ + _shutdown\ + _argtest\ + _screen\ + +fs.img: mkfs $(UPROGS) + ./mkfs fs.img $(UPROGS) + +-include *.d + +clean: + rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \ + *.o *.d *.asm *.sym vectors.S bootblock entryother \ + initcode initcode.out kernel xv6.img fs.img kernelmemfs \ + xv6memfs.img mkfs .gdbinit \ + syscall.h syscalltable.h usys.S \ + $(UPROGS) + +# run in emulators + +# try to generate a unique GDB port +GDBPORT = $(shell expr `id -u` % 5000 + 25000) +# QEMU's gdb stub command line changed in 0.11 +QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \ + then echo "-gdb tcp::$(GDBPORT)"; \ + else echo "-s -p $(GDBPORT)"; fi) +ifndef CPUS +CPUS := 2 +endif +QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA) + +qemu: fs.img xv6.img + $(QEMU) -vga std -serial mon:stdio $(QEMUOPTS) + +qemu-memfs: xv6memfs.img + $(QEMU) -vga std -drive file=xv6memfs.img,index=0,media=disk,format=raw -smp $(CPUS) -m 256 + +qemu-nox: fs.img xv6.img + $(QEMU) -nographic $(QEMUOPTS) + +qemu-curses: fs.img xv6.img + $(QEMU) -curses $(QEMUOPTS) + +.gdbinit: .gdbinit.tmpl + sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@ + +qemu-gdb: fs.img xv6.img .gdbinit + @echo "*** Now run 'gdb'." 1>&2 + $(QEMU) -vga std -serial mon:stdio $(QEMUOPTS) -S $(QEMUGDB) + +qemu-nox-gdb: fs.img xv6.img .gdbinit + @echo "*** Now run 'gdb'." 1>&2 + $(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB) diff --git a/_argtest b/_argtest new file mode 100644 index 0000000..cb6a2dd Binary files /dev/null and b/_argtest differ diff --git a/_cat b/_cat new file mode 100644 index 0000000..6912b31 Binary files /dev/null and b/_cat differ diff --git a/_echo b/_echo new file mode 100644 index 0000000..fffe6f0 Binary files /dev/null and b/_echo differ diff --git a/_forktest b/_forktest new file mode 100644 index 0000000..d0b763b Binary files /dev/null and b/_forktest differ diff --git a/_grep b/_grep new file mode 100644 index 0000000..5900456 Binary files /dev/null and b/_grep differ diff --git a/_hello b/_hello new file mode 100644 index 0000000..4605490 Binary files /dev/null and b/_hello differ diff --git a/_init b/_init new file mode 100644 index 0000000..72d39ef Binary files /dev/null and b/_init differ diff --git a/_kill b/_kill new file mode 100644 index 0000000..c86f470 Binary files /dev/null and b/_kill differ diff --git a/_ln b/_ln new file mode 100644 index 0000000..f8eb52e Binary files /dev/null and b/_ln differ diff --git a/_ls b/_ls new file mode 100644 index 0000000..00c0b1f Binary files /dev/null and b/_ls differ diff --git a/_mkdir b/_mkdir new file mode 100644 index 0000000..f88bbb2 Binary files /dev/null and b/_mkdir differ diff --git a/_rm b/_rm new file mode 100644 index 0000000..c5e2c7c Binary files /dev/null and b/_rm differ diff --git a/_screen b/_screen new file mode 100644 index 0000000..53a56aa Binary files /dev/null and b/_screen differ diff --git a/_sh b/_sh new file mode 100644 index 0000000..834031b Binary files /dev/null and b/_sh differ diff --git a/_shutdown b/_shutdown new file mode 100644 index 0000000..5ed067d Binary files /dev/null and b/_shutdown differ diff --git a/_stressfs b/_stressfs new file mode 100644 index 0000000..8a9004f Binary files /dev/null and b/_stressfs differ diff --git a/_usertests b/_usertests new file mode 100644 index 0000000..d9e85c8 Binary files /dev/null and b/_usertests differ diff --git a/_wc b/_wc new file mode 100644 index 0000000..b90c872 Binary files /dev/null and b/_wc differ diff --git a/_zombie b/_zombie new file mode 100644 index 0000000..de8668a Binary files /dev/null and b/_zombie differ diff --git a/argtest.asm b/argtest.asm new file mode 100644 index 0000000..8e7be3e --- /dev/null +++ b/argtest.asm @@ -0,0 +1,1162 @@ + +_argtest: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: 53 push %ebx + 10: 51 push %ecx + 11: 83 ec 08 sub $0x8,%esp + 14: 8b 31 mov (%ecx),%esi + 16: 8b 79 04 mov 0x4(%ecx),%edi + for (int i = 1; i < argc; i++) { + 19: 83 fe 01 cmp $0x1,%esi + 1c: 7e 24 jle 42 + 1e: bb 01 00 00 00 mov $0x1,%ebx + 23: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 27: 90 nop + printf(1, "Arg %d: %s\n", i, argv[i]); + 28: ff 34 9f push (%edi,%ebx,4) + 2b: 53 push %ebx + for (int i = 1; i < argc; i++) { + 2c: 83 c3 01 add $0x1,%ebx + printf(1, "Arg %d: %s\n", i, argv[i]); + 2f: 68 38 07 00 00 push $0x738 + 34: 6a 01 push $0x1 + 36: e8 d5 03 00 00 call 410 + for (int i = 1; i < argc; i++) { + 3b: 83 c4 10 add $0x10,%esp + 3e: 39 de cmp %ebx,%esi + 40: 75 e6 jne 28 + } + + exit(); + 42: e8 5c 02 00 00 call 2a3 + 47: 66 90 xchg %ax,%ax + 49: 66 90 xchg %ax,%ax + 4b: 66 90 xchg %ax,%ax + 4d: 66 90 xchg %ax,%ax + 4f: 90 nop + +00000050 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 50: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 51: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 53: 89 e5 mov %esp,%ebp + 55: 53 push %ebx + 56: 8b 4d 08 mov 0x8(%ebp),%ecx + 59: 8b 5d 0c mov 0xc(%ebp),%ebx + 5c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 60: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 64: 88 14 01 mov %dl,(%ecx,%eax,1) + 67: 83 c0 01 add $0x1,%eax + 6a: 84 d2 test %dl,%dl + 6c: 75 f2 jne 60 + ; + } + return os; +} + 6e: 8b 5d fc mov -0x4(%ebp),%ebx + 71: 89 c8 mov %ecx,%eax + 73: c9 leave + 74: c3 ret + 75: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 7c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000080 : + +int strcmp(const char *p, const char *q) { + 80: 55 push %ebp + 81: 89 e5 mov %esp,%ebp + 83: 53 push %ebx + 84: 8b 55 08 mov 0x8(%ebp),%edx + 87: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 8a: 0f b6 02 movzbl (%edx),%eax + 8d: 84 c0 test %al,%al + 8f: 75 17 jne a8 + 91: eb 3a jmp cd + 93: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 97: 90 nop + 98: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 9c: 83 c2 01 add $0x1,%edx + 9f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + a2: 84 c0 test %al,%al + a4: 74 1a je c0 + p++, q++; + a6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + a8: 0f b6 19 movzbl (%ecx),%ebx + ab: 38 c3 cmp %al,%bl + ad: 74 e9 je 98 + } + return (uchar) * p - (uchar) * q; + af: 29 d8 sub %ebx,%eax +} + b1: 8b 5d fc mov -0x4(%ebp),%ebx + b4: c9 leave + b5: c3 ret + b6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + bd: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + c0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + c4: 31 c0 xor %eax,%eax + c6: 29 d8 sub %ebx,%eax +} + c8: 8b 5d fc mov -0x4(%ebp),%ebx + cb: c9 leave + cc: c3 ret + return (uchar) * p - (uchar) * q; + cd: 0f b6 19 movzbl (%ecx),%ebx + d0: 31 c0 xor %eax,%eax + d2: eb db jmp af + d4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + db: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + df: 90 nop + +000000e0 : + +uint strlen(const char *s) { + e0: 55 push %ebp + e1: 89 e5 mov %esp,%ebp + e3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + e6: 80 3a 00 cmpb $0x0,(%edx) + e9: 74 15 je 100 + eb: 31 c0 xor %eax,%eax + ed: 8d 76 00 lea 0x0(%esi),%esi + f0: 83 c0 01 add $0x1,%eax + f3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + f7: 89 c1 mov %eax,%ecx + f9: 75 f5 jne f0 + ; + } + return n; +} + fb: 89 c8 mov %ecx,%eax + fd: 5d pop %ebp + fe: c3 ret + ff: 90 nop + for (n = 0; s[n]; n++) { + 100: 31 c9 xor %ecx,%ecx +} + 102: 5d pop %ebp + 103: 89 c8 mov %ecx,%eax + 105: c3 ret + 106: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 10d: 8d 76 00 lea 0x0(%esi),%esi + +00000110 : + +void* memset(void *dst, int c, uint n) { + 110: 55 push %ebp + 111: 89 e5 mov %esp,%ebp + 113: 57 push %edi + 114: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 117: 8b 4d 10 mov 0x10(%ebp),%ecx + 11a: 8b 45 0c mov 0xc(%ebp),%eax + 11d: 89 d7 mov %edx,%edi + 11f: fc cld + 120: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 122: 8b 7d fc mov -0x4(%ebp),%edi + 125: 89 d0 mov %edx,%eax + 127: c9 leave + 128: c3 ret + 129: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000130 : + +char* strchr(const char *s, char c) { + 130: 55 push %ebp + 131: 89 e5 mov %esp,%ebp + 133: 8b 45 08 mov 0x8(%ebp),%eax + 136: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 13a: 0f b6 10 movzbl (%eax),%edx + 13d: 84 d2 test %dl,%dl + 13f: 75 12 jne 153 + 141: eb 1d jmp 160 + 143: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 147: 90 nop + 148: 0f b6 50 01 movzbl 0x1(%eax),%edx + 14c: 83 c0 01 add $0x1,%eax + 14f: 84 d2 test %dl,%dl + 151: 74 0d je 160 + if (*s == c) { + 153: 38 d1 cmp %dl,%cl + 155: 75 f1 jne 148 + return (char*)s; + } + } + return 0; +} + 157: 5d pop %ebp + 158: c3 ret + 159: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 160: 31 c0 xor %eax,%eax +} + 162: 5d pop %ebp + 163: c3 ret + 164: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 16b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 16f: 90 nop + +00000170 : + +char* gets(char *buf, int max) { + 170: 55 push %ebp + 171: 89 e5 mov %esp,%ebp + 173: 57 push %edi + 174: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 175: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 178: 53 push %ebx + for (i = 0; i + 1 < max;) { + 179: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 17b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 17e: eb 27 jmp 1a7 + cc = read(0, &c, 1); + 180: 83 ec 04 sub $0x4,%esp + 183: 6a 01 push $0x1 + 185: 57 push %edi + 186: 6a 00 push $0x0 + 188: e8 2e 01 00 00 call 2bb + if (cc < 1) { + 18d: 83 c4 10 add $0x10,%esp + 190: 85 c0 test %eax,%eax + 192: 7e 1d jle 1b1 + break; + } + buf[i++] = c; + 194: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 198: 8b 55 08 mov 0x8(%ebp),%edx + 19b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 19f: 3c 0a cmp $0xa,%al + 1a1: 74 1d je 1c0 + 1a3: 3c 0d cmp $0xd,%al + 1a5: 74 19 je 1c0 + for (i = 0; i + 1 < max;) { + 1a7: 89 de mov %ebx,%esi + 1a9: 83 c3 01 add $0x1,%ebx + 1ac: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1af: 7c cf jl 180 + break; + } + } + buf[i] = '\0'; + 1b1: 8b 45 08 mov 0x8(%ebp),%eax + 1b4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1b8: 8d 65 f4 lea -0xc(%ebp),%esp + 1bb: 5b pop %ebx + 1bc: 5e pop %esi + 1bd: 5f pop %edi + 1be: 5d pop %ebp + 1bf: c3 ret + buf[i] = '\0'; + 1c0: 8b 45 08 mov 0x8(%ebp),%eax + 1c3: 89 de mov %ebx,%esi + 1c5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 1c9: 8d 65 f4 lea -0xc(%ebp),%esp + 1cc: 5b pop %ebx + 1cd: 5e pop %esi + 1ce: 5f pop %edi + 1cf: 5d pop %ebp + 1d0: c3 ret + 1d1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1d8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1df: 90 nop + +000001e0 : + +int stat(const char *n, struct stat *st) { + 1e0: 55 push %ebp + 1e1: 89 e5 mov %esp,%ebp + 1e3: 56 push %esi + 1e4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 1e5: 83 ec 08 sub $0x8,%esp + 1e8: 6a 00 push $0x0 + 1ea: ff 75 08 push 0x8(%ebp) + 1ed: e8 19 01 00 00 call 30b + if (fd < 0) { + 1f2: 83 c4 10 add $0x10,%esp + 1f5: 85 c0 test %eax,%eax + 1f7: 78 27 js 220 + return -1; + } + r = fstat(fd, st); + 1f9: 83 ec 08 sub $0x8,%esp + 1fc: ff 75 0c push 0xc(%ebp) + 1ff: 89 c3 mov %eax,%ebx + 201: 50 push %eax + 202: e8 cc 00 00 00 call 2d3 + close(fd); + 207: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 20a: 89 c6 mov %eax,%esi + close(fd); + 20c: e8 2a 01 00 00 call 33b + return r; + 211: 83 c4 10 add $0x10,%esp +} + 214: 8d 65 f8 lea -0x8(%ebp),%esp + 217: 89 f0 mov %esi,%eax + 219: 5b pop %ebx + 21a: 5e pop %esi + 21b: 5d pop %ebp + 21c: c3 ret + 21d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 220: be ff ff ff ff mov $0xffffffff,%esi + 225: eb ed jmp 214 + 227: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 22e: 66 90 xchg %ax,%ax + +00000230 : + +int atoi(const char *s) { + 230: 55 push %ebp + 231: 89 e5 mov %esp,%ebp + 233: 53 push %ebx + 234: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 237: 0f be 02 movsbl (%edx),%eax + 23a: 8d 48 d0 lea -0x30(%eax),%ecx + 23d: 80 f9 09 cmp $0x9,%cl + n = 0; + 240: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 245: 77 1e ja 265 + 247: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 24e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 250: 83 c2 01 add $0x1,%edx + 253: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 256: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 25a: 0f be 02 movsbl (%edx),%eax + 25d: 8d 58 d0 lea -0x30(%eax),%ebx + 260: 80 fb 09 cmp $0x9,%bl + 263: 76 eb jbe 250 + } + return n; +} + 265: 8b 5d fc mov -0x4(%ebp),%ebx + 268: 89 c8 mov %ecx,%eax + 26a: c9 leave + 26b: c3 ret + 26c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000270 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 270: 55 push %ebp + 271: 89 e5 mov %esp,%ebp + 273: 57 push %edi + 274: 8b 45 10 mov 0x10(%ebp),%eax + 277: 8b 55 08 mov 0x8(%ebp),%edx + 27a: 56 push %esi + 27b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 27e: 85 c0 test %eax,%eax + 280: 7e 13 jle 295 + 282: 01 d0 add %edx,%eax + dst = vdst; + 284: 89 d7 mov %edx,%edi + 286: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 28d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 290: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 291: 39 f8 cmp %edi,%eax + 293: 75 fb jne 290 + } + return vdst; +} + 295: 5e pop %esi + 296: 89 d0 mov %edx,%eax + 298: 5f pop %edi + 299: 5d pop %ebp + 29a: c3 ret + +0000029b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 29b: b8 01 00 00 00 mov $0x1,%eax + 2a0: cd 40 int $0x40 + 2a2: c3 ret + +000002a3 : +SYSCALL(exit) + 2a3: b8 02 00 00 00 mov $0x2,%eax + 2a8: cd 40 int $0x40 + 2aa: c3 ret + +000002ab : +SYSCALL(wait) + 2ab: b8 03 00 00 00 mov $0x3,%eax + 2b0: cd 40 int $0x40 + 2b2: c3 ret + +000002b3 : +SYSCALL(pipe) + 2b3: b8 04 00 00 00 mov $0x4,%eax + 2b8: cd 40 int $0x40 + 2ba: c3 ret + +000002bb : +SYSCALL(read) + 2bb: b8 05 00 00 00 mov $0x5,%eax + 2c0: cd 40 int $0x40 + 2c2: c3 ret + +000002c3 : +SYSCALL(kill) + 2c3: b8 06 00 00 00 mov $0x6,%eax + 2c8: cd 40 int $0x40 + 2ca: c3 ret + +000002cb : +SYSCALL(exec) + 2cb: b8 07 00 00 00 mov $0x7,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(fstat) + 2d3: b8 08 00 00 00 mov $0x8,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(chdir) + 2db: b8 09 00 00 00 mov $0x9,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(dup) + 2e3: b8 0a 00 00 00 mov $0xa,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(getpid) + 2eb: b8 0b 00 00 00 mov $0xb,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(sbrk) + 2f3: b8 0c 00 00 00 mov $0xc,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(sleep) + 2fb: b8 0d 00 00 00 mov $0xd,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(uptime) + 303: b8 0e 00 00 00 mov $0xe,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(open) + 30b: b8 0f 00 00 00 mov $0xf,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(write) + 313: b8 10 00 00 00 mov $0x10,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(mknod) + 31b: b8 11 00 00 00 mov $0x11,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(unlink) + 323: b8 12 00 00 00 mov $0x12,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(link) + 32b: b8 13 00 00 00 mov $0x13,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(mkdir) + 333: b8 14 00 00 00 mov $0x14,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(close) + 33b: b8 15 00 00 00 mov $0x15,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(getch) + 343: b8 16 00 00 00 mov $0x16,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(greeting) + 34b: b8 17 00 00 00 mov $0x17,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(shutdown) + 353: b8 18 00 00 00 mov $0x18,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + 35b: 66 90 xchg %ax,%ax + 35d: 66 90 xchg %ax,%ax + 35f: 90 nop + +00000360 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 360: 55 push %ebp + 361: 89 e5 mov %esp,%ebp + 363: 57 push %edi + 364: 56 push %esi + 365: 53 push %ebx + 366: 83 ec 3c sub $0x3c,%esp + 369: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 36c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 36e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 371: 85 d2 test %edx,%edx + 373: 0f 89 7f 00 00 00 jns 3f8 + 379: f6 45 08 01 testb $0x1,0x8(%ebp) + 37d: 74 79 je 3f8 + neg = 1; + 37f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 386: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 388: 31 db xor %ebx,%ebx + 38a: 8d 75 d7 lea -0x29(%ebp),%esi + 38d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 390: 89 c8 mov %ecx,%eax + 392: 31 d2 xor %edx,%edx + 394: 89 cf mov %ecx,%edi + 396: f7 75 c4 divl -0x3c(%ebp) + 399: 0f b6 92 a4 07 00 00 movzbl 0x7a4(%edx),%edx + 3a0: 89 45 c0 mov %eax,-0x40(%ebp) + 3a3: 89 d8 mov %ebx,%eax + 3a5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3a8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3ab: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3ae: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3b1: 76 dd jbe 390 + if (neg) { + 3b3: 8b 4d bc mov -0x44(%ebp),%ecx + 3b6: 85 c9 test %ecx,%ecx + 3b8: 74 0c je 3c6 + buf[i++] = '-'; + 3ba: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3bf: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 3c1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 3c6: 8b 7d b8 mov -0x48(%ebp),%edi + 3c9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 3cd: eb 07 jmp 3d6 + 3cf: 90 nop + putc(fd, buf[i]); + 3d0: 0f b6 13 movzbl (%ebx),%edx + 3d3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 3d6: 83 ec 04 sub $0x4,%esp + 3d9: 88 55 d7 mov %dl,-0x29(%ebp) + 3dc: 6a 01 push $0x1 + 3de: 56 push %esi + 3df: 57 push %edi + 3e0: e8 2e ff ff ff call 313 + while (--i >= 0) { + 3e5: 83 c4 10 add $0x10,%esp + 3e8: 39 de cmp %ebx,%esi + 3ea: 75 e4 jne 3d0 + } +} + 3ec: 8d 65 f4 lea -0xc(%ebp),%esp + 3ef: 5b pop %ebx + 3f0: 5e pop %esi + 3f1: 5f pop %edi + 3f2: 5d pop %ebp + 3f3: c3 ret + 3f4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 3f8: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 3ff: eb 87 jmp 388 + 401: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 408: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 40f: 90 nop + +00000410 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 410: 55 push %ebp + 411: 89 e5 mov %esp,%ebp + 413: 57 push %edi + 414: 56 push %esi + 415: 53 push %ebx + 416: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 419: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 41c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 41f: 0f b6 13 movzbl (%ebx),%edx + 422: 84 d2 test %dl,%dl + 424: 74 6a je 490 + ap = (uint*)(void*)&fmt + 1; + 426: 8d 45 10 lea 0x10(%ebp),%eax + 429: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 42c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 42f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 431: 89 45 d0 mov %eax,-0x30(%ebp) + 434: eb 36 jmp 46c + 436: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 43d: 8d 76 00 lea 0x0(%esi),%esi + 440: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 443: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 448: 83 f8 25 cmp $0x25,%eax + 44b: 74 15 je 462 + write(fd, &c, 1); + 44d: 83 ec 04 sub $0x4,%esp + 450: 88 55 e7 mov %dl,-0x19(%ebp) + 453: 6a 01 push $0x1 + 455: 57 push %edi + 456: 56 push %esi + 457: e8 b7 fe ff ff call 313 + 45c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 45f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 462: 0f b6 13 movzbl (%ebx),%edx + 465: 83 c3 01 add $0x1,%ebx + 468: 84 d2 test %dl,%dl + 46a: 74 24 je 490 + c = fmt[i] & 0xff; + 46c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 46f: 85 c9 test %ecx,%ecx + 471: 74 cd je 440 + } + } + else if (state == '%') { + 473: 83 f9 25 cmp $0x25,%ecx + 476: 75 ea jne 462 + if (c == 'd') { + 478: 83 f8 25 cmp $0x25,%eax + 47b: 0f 84 07 01 00 00 je 588 + 481: 83 e8 63 sub $0x63,%eax + 484: 83 f8 15 cmp $0x15,%eax + 487: 77 17 ja 4a0 + 489: ff 24 85 4c 07 00 00 jmp *0x74c(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 490: 8d 65 f4 lea -0xc(%ebp),%esp + 493: 5b pop %ebx + 494: 5e pop %esi + 495: 5f pop %edi + 496: 5d pop %ebp + 497: c3 ret + 498: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 49f: 90 nop + write(fd, &c, 1); + 4a0: 83 ec 04 sub $0x4,%esp + 4a3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4a6: 6a 01 push $0x1 + 4a8: 57 push %edi + 4a9: 56 push %esi + 4aa: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4ae: e8 60 fe ff ff call 313 + putc(fd, c); + 4b3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4b7: 83 c4 0c add $0xc,%esp + 4ba: 88 55 e7 mov %dl,-0x19(%ebp) + 4bd: 6a 01 push $0x1 + 4bf: 57 push %edi + 4c0: 56 push %esi + 4c1: e8 4d fe ff ff call 313 + putc(fd, c); + 4c6: 83 c4 10 add $0x10,%esp + state = 0; + 4c9: 31 c9 xor %ecx,%ecx + 4cb: eb 95 jmp 462 + 4cd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 4d0: 83 ec 0c sub $0xc,%esp + 4d3: b9 10 00 00 00 mov $0x10,%ecx + 4d8: 6a 00 push $0x0 + 4da: 8b 45 d0 mov -0x30(%ebp),%eax + 4dd: 8b 10 mov (%eax),%edx + 4df: 89 f0 mov %esi,%eax + 4e1: e8 7a fe ff ff call 360 + ap++; + 4e6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 4ea: 83 c4 10 add $0x10,%esp + state = 0; + 4ed: 31 c9 xor %ecx,%ecx + 4ef: e9 6e ff ff ff jmp 462 + 4f4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 4f8: 8b 45 d0 mov -0x30(%ebp),%eax + 4fb: 8b 10 mov (%eax),%edx + ap++; + 4fd: 83 c0 04 add $0x4,%eax + 500: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 503: 85 d2 test %edx,%edx + 505: 0f 84 8d 00 00 00 je 598 + while (*s != 0) { + 50b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 50e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 510: 84 c0 test %al,%al + 512: 0f 84 4a ff ff ff je 462 + 518: 89 5d d4 mov %ebx,-0x2c(%ebp) + 51b: 89 d3 mov %edx,%ebx + 51d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 520: 83 ec 04 sub $0x4,%esp + s++; + 523: 83 c3 01 add $0x1,%ebx + 526: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 529: 6a 01 push $0x1 + 52b: 57 push %edi + 52c: 56 push %esi + 52d: e8 e1 fd ff ff call 313 + while (*s != 0) { + 532: 0f b6 03 movzbl (%ebx),%eax + 535: 83 c4 10 add $0x10,%esp + 538: 84 c0 test %al,%al + 53a: 75 e4 jne 520 + state = 0; + 53c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 53f: 31 c9 xor %ecx,%ecx + 541: e9 1c ff ff ff jmp 462 + 546: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 54d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 550: 83 ec 0c sub $0xc,%esp + 553: b9 0a 00 00 00 mov $0xa,%ecx + 558: 6a 01 push $0x1 + 55a: e9 7b ff ff ff jmp 4da + 55f: 90 nop + putc(fd, *ap); + 560: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 563: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 566: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 568: 6a 01 push $0x1 + 56a: 57 push %edi + 56b: 56 push %esi + putc(fd, *ap); + 56c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 56f: e8 9f fd ff ff call 313 + ap++; + 574: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 578: 83 c4 10 add $0x10,%esp + state = 0; + 57b: 31 c9 xor %ecx,%ecx + 57d: e9 e0 fe ff ff jmp 462 + 582: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 588: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 58b: 83 ec 04 sub $0x4,%esp + 58e: e9 2a ff ff ff jmp 4bd + 593: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 597: 90 nop + s = "(null)"; + 598: ba 44 07 00 00 mov $0x744,%edx + while (*s != 0) { + 59d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5a0: b8 28 00 00 00 mov $0x28,%eax + 5a5: 89 d3 mov %edx,%ebx + 5a7: e9 74 ff ff ff jmp 520 + 5ac: 66 90 xchg %ax,%ax + 5ae: 66 90 xchg %ax,%ax + +000005b0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5b0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5b1: a1 58 0a 00 00 mov 0xa58,%eax +void free(void *ap) { + 5b6: 89 e5 mov %esp,%ebp + 5b8: 57 push %edi + 5b9: 56 push %esi + 5ba: 53 push %ebx + 5bb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5be: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5c8: 89 c2 mov %eax,%edx + 5ca: 8b 00 mov (%eax),%eax + 5cc: 39 ca cmp %ecx,%edx + 5ce: 73 30 jae 600 + 5d0: 39 c1 cmp %eax,%ecx + 5d2: 72 04 jb 5d8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 5d4: 39 c2 cmp %eax,%edx + 5d6: 72 f0 jb 5c8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 5d8: 8b 73 fc mov -0x4(%ebx),%esi + 5db: 8d 3c f1 lea (%ecx,%esi,8),%edi + 5de: 39 f8 cmp %edi,%eax + 5e0: 74 30 je 612 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 5e2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 5e5: 8b 42 04 mov 0x4(%edx),%eax + 5e8: 8d 34 c2 lea (%edx,%eax,8),%esi + 5eb: 39 f1 cmp %esi,%ecx + 5ed: 74 3a je 629 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 5ef: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 5f1: 5b pop %ebx + freep = p; + 5f2: 89 15 58 0a 00 00 mov %edx,0xa58 +} + 5f8: 5e pop %esi + 5f9: 5f pop %edi + 5fa: 5d pop %ebp + 5fb: c3 ret + 5fc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 600: 39 c2 cmp %eax,%edx + 602: 72 c4 jb 5c8 + 604: 39 c1 cmp %eax,%ecx + 606: 73 c0 jae 5c8 + if (bp + bp->s.size == p->s.ptr) { + 608: 8b 73 fc mov -0x4(%ebx),%esi + 60b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 60e: 39 f8 cmp %edi,%eax + 610: 75 d0 jne 5e2 + bp->s.size += p->s.ptr->s.size; + 612: 03 70 04 add 0x4(%eax),%esi + 615: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 618: 8b 02 mov (%edx),%eax + 61a: 8b 00 mov (%eax),%eax + 61c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 61f: 8b 42 04 mov 0x4(%edx),%eax + 622: 8d 34 c2 lea (%edx,%eax,8),%esi + 625: 39 f1 cmp %esi,%ecx + 627: 75 c6 jne 5ef + p->s.size += bp->s.size; + 629: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 62c: 89 15 58 0a 00 00 mov %edx,0xa58 + p->s.size += bp->s.size; + 632: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 635: 8b 4b f8 mov -0x8(%ebx),%ecx + 638: 89 0a mov %ecx,(%edx) +} + 63a: 5b pop %ebx + 63b: 5e pop %esi + 63c: 5f pop %edi + 63d: 5d pop %ebp + 63e: c3 ret + 63f: 90 nop + +00000640 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 640: 55 push %ebp + 641: 89 e5 mov %esp,%ebp + 643: 57 push %edi + 644: 56 push %esi + 645: 53 push %ebx + 646: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 649: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 64c: 8b 3d 58 0a 00 00 mov 0xa58,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 652: 8d 70 07 lea 0x7(%eax),%esi + 655: c1 ee 03 shr $0x3,%esi + 658: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 65b: 85 ff test %edi,%edi + 65d: 0f 84 9d 00 00 00 je 700 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 663: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 665: 8b 4a 04 mov 0x4(%edx),%ecx + 668: 39 f1 cmp %esi,%ecx + 66a: 73 6a jae 6d6 + 66c: bb 00 10 00 00 mov $0x1000,%ebx + 671: 39 de cmp %ebx,%esi + 673: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 676: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 67d: 89 45 e4 mov %eax,-0x1c(%ebp) + 680: eb 17 jmp 699 + 682: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 688: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 68a: 8b 48 04 mov 0x4(%eax),%ecx + 68d: 39 f1 cmp %esi,%ecx + 68f: 73 4f jae 6e0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 691: 8b 3d 58 0a 00 00 mov 0xa58,%edi + 697: 89 c2 mov %eax,%edx + 699: 39 d7 cmp %edx,%edi + 69b: 75 eb jne 688 + p = sbrk(nu * sizeof(Header)); + 69d: 83 ec 0c sub $0xc,%esp + 6a0: ff 75 e4 push -0x1c(%ebp) + 6a3: e8 4b fc ff ff call 2f3 + if (p == (char*)-1) { + 6a8: 83 c4 10 add $0x10,%esp + 6ab: 83 f8 ff cmp $0xffffffff,%eax + 6ae: 74 1c je 6cc + hp->s.size = nu; + 6b0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6b3: 83 ec 0c sub $0xc,%esp + 6b6: 83 c0 08 add $0x8,%eax + 6b9: 50 push %eax + 6ba: e8 f1 fe ff ff call 5b0 + return freep; + 6bf: 8b 15 58 0a 00 00 mov 0xa58,%edx + if ((p = morecore(nunits)) == 0) { + 6c5: 83 c4 10 add $0x10,%esp + 6c8: 85 d2 test %edx,%edx + 6ca: 75 bc jne 688 + return 0; + } + } + } +} + 6cc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 6cf: 31 c0 xor %eax,%eax +} + 6d1: 5b pop %ebx + 6d2: 5e pop %esi + 6d3: 5f pop %edi + 6d4: 5d pop %ebp + 6d5: c3 ret + if (p->s.size >= nunits) { + 6d6: 89 d0 mov %edx,%eax + 6d8: 89 fa mov %edi,%edx + 6da: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 6e0: 39 ce cmp %ecx,%esi + 6e2: 74 4c je 730 + p->s.size -= nunits; + 6e4: 29 f1 sub %esi,%ecx + 6e6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 6e9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 6ec: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 6ef: 89 15 58 0a 00 00 mov %edx,0xa58 +} + 6f5: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 6f8: 83 c0 08 add $0x8,%eax +} + 6fb: 5b pop %ebx + 6fc: 5e pop %esi + 6fd: 5f pop %edi + 6fe: 5d pop %ebp + 6ff: c3 ret + base.s.ptr = freep = prevp = &base; + 700: c7 05 58 0a 00 00 5c movl $0xa5c,0xa58 + 707: 0a 00 00 + base.s.size = 0; + 70a: bf 5c 0a 00 00 mov $0xa5c,%edi + base.s.ptr = freep = prevp = &base; + 70f: c7 05 5c 0a 00 00 5c movl $0xa5c,0xa5c + 716: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 719: 89 fa mov %edi,%edx + base.s.size = 0; + 71b: c7 05 60 0a 00 00 00 movl $0x0,0xa60 + 722: 00 00 00 + if (p->s.size >= nunits) { + 725: e9 42 ff ff ff jmp 66c + 72a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 730: 8b 08 mov (%eax),%ecx + 732: 89 0a mov %ecx,(%edx) + 734: eb b9 jmp 6ef diff --git a/argtest.c b/argtest.c new file mode 100644 index 0000000..e915cd6 --- /dev/null +++ b/argtest.c @@ -0,0 +1,10 @@ +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + for (int i = 1; i < argc; i++) { + printf(1, "Arg %d: %s\n", i, argv[i]); + } + + exit(); +} \ No newline at end of file diff --git a/argtest.d b/argtest.d new file mode 100644 index 0000000..2c57752 --- /dev/null +++ b/argtest.d @@ -0,0 +1 @@ +argtest.o: argtest.c /usr/include/stdc-predef.h types.h user.h diff --git a/argtest.o b/argtest.o new file mode 100644 index 0000000..979a741 Binary files /dev/null and b/argtest.o differ diff --git a/argtest.sym b/argtest.sym new file mode 100644 index 0000000..d19cced --- /dev/null +++ b/argtest.sym @@ -0,0 +1,48 @@ +00000000 argtest.c +00000000 ulib.c +00000000 printf.c +00000360 printint +000007a4 digits.0 +00000000 umalloc.c +00000a58 freep +00000a5c base +00000050 strcpy +00000410 printf +0000034b greeting +00000270 memmove +0000031b mknod +00000170 gets +000002eb getpid +00000640 malloc +000002fb sleep +000002b3 pipe +00000343 getch +00000313 write +000002d3 fstat +000002c3 kill +000002db chdir +000002cb exec +000002ab wait +000002bb read +00000323 unlink +0000029b fork +000002f3 sbrk +00000303 uptime +00000a58 __bss_start +00000110 memset +00000000 main +00000080 strcmp +00000353 shutdown +000002e3 dup +000001e0 stat +00000a58 _edata +00000a64 _end +0000032b link +000002a3 exit +00000230 atoi +000000e0 strlen +0000030b open +00000130 strchr +00000333 mkdir +0000033b close +000005b0 free diff --git a/asm.h b/asm.h new file mode 100644 index 0000000..4a92aad --- /dev/null +++ b/asm.h @@ -0,0 +1,18 @@ +// +// assembler macros to create x86 segments +// + +#define SEG_NULLASM \ + .word 0, 0; \ + .byte 0, 0, 0, 0 + +// The 0xC0 means the limit is in 4096-byte units +// and (for executable segments) 32-bit mode. +#define SEG_ASM(type, base, lim) \ + .word(((lim) >> 12) & 0xffff), ((base) & 0xffff); \ + .byte(((base) >> 16) & 0xff), (0x90 | (type)), \ + (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) + +#define STA_X 0x8 // Executable segment +#define STA_W 0x2 // Writeable (non-executable segments) +#define STA_R 0x2 // Readable (executable segments) diff --git a/bio.c b/bio.c new file mode 100644 index 0000000..8faaf8c --- /dev/null +++ b/bio.c @@ -0,0 +1,140 @@ +// Buffer cache. +// +// The buffer cache is a linked list of buf structures holding +// cached copies of disk block contents. Caching disk blocks +// in memory reduces the number of disk reads and also provides +// a synchronization point for disk blocks used by multiple processes. +// +// Interface: +// * To get a buffer for a particular disk block, call bread. +// * After changing buffer data, call bwrite to write it to disk. +// * When done with the buffer, call brelse. +// * Do not use the buffer after calling brelse. +// * Only one process at a time can use a buffer, +// so do not keep them longer than necessary. +// +// The implementation uses two state flags internally: +// * B_VALID: the buffer data has been read from the disk. +// * B_DIRTY: the buffer data has been modified +// and needs to be written to disk. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "fs.h" +#include "buf.h" + +struct { + struct spinlock lock; + struct buf buf[NBUF]; + + // Linked list of all buffers, through prev/next. + // head.next is most recently used. + struct buf head; +} bcache; + +void binit(void) { + struct buf *b; + + initlock(&bcache.lock, "bcache"); + + // Create linked list of buffers + bcache.head.prev = &bcache.head; + bcache.head.next = &bcache.head; + for (b = bcache.buf; b < bcache.buf + NBUF; b++) { + b->next = bcache.head.next; + b->prev = &bcache.head; + initsleeplock(&b->lock, "buffer"); + bcache.head.next->prev = b; + bcache.head.next = b; + } +} + +// Look through buffer cache for block on device dev. +// If not found, allocate a buffer. +// In either case, return locked buffer. + +static struct buf* bget(uint dev, uint blockno) { + struct buf *b; + + acquire(&bcache.lock); + + // Is the block already cached? + for (b = bcache.head.next; b != &bcache.head; b = b->next) { + if (b->dev == dev && b->blockno == blockno) { + b->refcnt++; + release(&bcache.lock); + acquiresleep(&b->lock); + return b; + } + } + + // Not cached; recycle an unused buffer. + // Even if refcnt==0, B_DIRTY indicates a buffer is in use + // because log.c has modified it but not yet committed it. + + for (b = bcache.head.prev; b != &bcache.head; b = b->prev) { + if (b->refcnt == 0 && (b->flags & B_DIRTY) == 0) { + b->dev = dev; + b->blockno = blockno; + b->flags = 0; + b->refcnt = 1; + release(&bcache.lock); + acquiresleep(&b->lock); + return b; + } + } + panic("bget: no buffers"); +} + +// Return a locked buf with the contents of the indicated block. + +struct buf*bread(uint dev, uint blockno) { + struct buf *b; + + b = bget(dev, blockno); + if ((b->flags & B_VALID) == 0) { + iderw(b); + } + return b; +} + +// Write b's contents to disk. Must be locked. + +void bwrite(struct buf *b) { + if (!holdingsleep(&b->lock)) { + panic("bwrite"); + } + b->flags |= B_DIRTY; + iderw(b); +} + +// Release a locked buffer. +// Move to the head of the MRU list. + +void brelse(struct buf *b) { + if (!holdingsleep(&b->lock)) { + panic("brelse"); + } + + releasesleep(&b->lock); + + acquire(&bcache.lock); + b->refcnt--; + if (b->refcnt == 0) { + // no one is waiting for it. + b->next->prev = b->prev; + b->prev->next = b->next; + b->next = bcache.head.next; + b->prev = &bcache.head; + bcache.head.next->prev = b; + bcache.head.next = b; + } + + release(&bcache.lock); +} + + + diff --git a/bio.d b/bio.d new file mode 100644 index 0000000..b4bbd30 --- /dev/null +++ b/bio.d @@ -0,0 +1,2 @@ +bio.o: bio.c /usr/include/stdc-predef.h types.h defs.h param.h spinlock.h \ + sleeplock.h fs.h buf.h diff --git a/bio.o b/bio.o new file mode 100644 index 0000000..0535832 Binary files /dev/null and b/bio.o differ diff --git a/bootasm.S b/bootasm.S new file mode 100644 index 0000000..260a156 --- /dev/null +++ b/bootasm.S @@ -0,0 +1,81 @@ +#include "asm.h" +#include "memlayout.h" +#include "mmu.h" + +# Start the first CPU: switch to 32-bit protected mode, jump into C. +# The BIOS loads this code from the first sector of the hard disk into +# memory at physical address 0x7c00 and starts executing in real mode +# with %cs=0 %ip=7c00. + +.code16 # Assemble for 16-bit mode +.globl start +start: + cli # BIOS enabled interrupts; disable + + # Zero data segment registers DS, ES, and SS. + xorw %ax,%ax # Set %ax to zero + movw %ax,%ds # -> Data Segment + movw %ax,%es # -> Extra Segment + movw %ax,%ss # -> Stack Segment + + # Physical address line A20 is tied to zero so that the first PCs + # with 2 MB would run software that assumed 1 MB. Undo that. +seta20.1: + inb $0x64,%al # Wait for not busy + testb $0x2,%al + jnz seta20.1 + + movb $0xd1,%al # 0xd1 -> port 0x64 + outb %al,$0x64 + +seta20.2: + inb $0x64,%al # Wait for not busy + testb $0x2,%al + jnz seta20.2 + + movb $0xdf,%al # 0xdf -> port 0x60 + outb %al,$0x60 + + # Switch from real to protected mode. Use a bootstrap GDT that makes + # virtual addresses map directly to physical addresses so that the + # effective memory map doesn't change during the transition. + lgdt gdtdesc + movl %cr0, %eax + orl $CR0_PE, %eax + movl %eax, %cr0 + + # Complete the transition to 32-bit protected mode by using a long jmp + # to reload %cs and %eip. The segment descriptors are set up with no + # translation, so that the mapping is still the identity mapping. + ljmp $(SEG_KCODE<<3), $start32 + +.code32 # Tell assembler to generate 32-bit code now. +start32: + # Set up the protected-mode data segment registers + movw $(SEG_KDATA<<3), %ax # Our data segment selector + movw %ax, %ds # -> DS: Data Segment + movw %ax, %es # -> ES: Extra Segment + movw %ax, %ss # -> SS: Stack Segment + movw $0, %ax # Zero segments not ready for use + movw %ax, %fs # -> FS + movw %ax, %gs # -> GS + + # Set up the stack pointer and call into C. + movl $start, %esp + call bootmain + + # If bootmain returns (it shouldn't), loop. +spin: + jmp spin + + # Bootstrap GDT +.p2align 2 # force 4 byte alignment +gdt: + SEG_NULLASM # null seg + SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg + SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg + +gdtdesc: + .word (gdtdesc - gdt - 1) # sizeof(gdt) - 1 + .long gdt # address gdt + diff --git a/bootasm.d b/bootasm.d new file mode 100644 index 0000000..3b3dc19 --- /dev/null +++ b/bootasm.d @@ -0,0 +1 @@ +bootasm.o: bootasm.S asm.h memlayout.h mmu.h diff --git a/bootasm.o b/bootasm.o new file mode 100644 index 0000000..0db07cc Binary files /dev/null and b/bootasm.o differ diff --git a/bootblock b/bootblock new file mode 100644 index 0000000..ccebab4 Binary files /dev/null and b/bootblock differ diff --git a/bootblock.asm b/bootblock.asm new file mode 100644 index 0000000..bece2ca --- /dev/null +++ b/bootblock.asm @@ -0,0 +1,341 @@ + +bootblock.o: file format elf32-i386 + + +Disassembly of section .text: + +00007c00 : +# with %cs=0 %ip=7c00. + +.code16 # Assemble for 16-bit mode +.globl start +start: + cli # BIOS enabled interrupts; disable + 7c00: fa cli + + # Zero data segment registers DS, ES, and SS. + xorw %ax,%ax # Set %ax to zero + 7c01: 31 c0 xor %eax,%eax + movw %ax,%ds # -> Data Segment + 7c03: 8e d8 mov %eax,%ds + movw %ax,%es # -> Extra Segment + 7c05: 8e c0 mov %eax,%es + movw %ax,%ss # -> Stack Segment + 7c07: 8e d0 mov %eax,%ss + +00007c09 : + + # Physical address line A20 is tied to zero so that the first PCs + # with 2 MB would run software that assumed 1 MB. Undo that. +seta20.1: + inb $0x64,%al # Wait for not busy + 7c09: e4 64 in $0x64,%al + testb $0x2,%al + 7c0b: a8 02 test $0x2,%al + jnz seta20.1 + 7c0d: 75 fa jne 7c09 + + movb $0xd1,%al # 0xd1 -> port 0x64 + 7c0f: b0 d1 mov $0xd1,%al + outb %al,$0x64 + 7c11: e6 64 out %al,$0x64 + +00007c13 : + +seta20.2: + inb $0x64,%al # Wait for not busy + 7c13: e4 64 in $0x64,%al + testb $0x2,%al + 7c15: a8 02 test $0x2,%al + jnz seta20.2 + 7c17: 75 fa jne 7c13 + + movb $0xdf,%al # 0xdf -> port 0x60 + 7c19: b0 df mov $0xdf,%al + outb %al,$0x60 + 7c1b: e6 60 out %al,$0x60 + + # Switch from real to protected mode. Use a bootstrap GDT that makes + # virtual addresses map directly to physical addresses so that the + # effective memory map doesn't change during the transition. + lgdt gdtdesc + 7c1d: 0f 01 16 lgdtl (%esi) + 7c20: 68 7c 0f 20 c0 push $0xc0200f7c + movl %cr0, %eax + orl $CR0_PE, %eax + 7c25: 66 83 c8 01 or $0x1,%ax + movl %eax, %cr0 + 7c29: 0f 22 c0 mov %eax,%cr0 + + # Complete the transition to 32-bit protected mode by using a long jmp + # to reload %cs and %eip. The segment descriptors are set up with no + # translation, so that the mapping is still the identity mapping. + ljmp $(SEG_KCODE<<3), $start32 + 7c2c: ea .byte 0xea + 7c2d: 31 7c 08 00 xor %edi,0x0(%eax,%ecx,1) + +00007c31 : + +.code32 # Tell assembler to generate 32-bit code now. +start32: + # Set up the protected-mode data segment registers + movw $(SEG_KDATA<<3), %ax # Our data segment selector + 7c31: 66 b8 10 00 mov $0x10,%ax + movw %ax, %ds # -> DS: Data Segment + 7c35: 8e d8 mov %eax,%ds + movw %ax, %es # -> ES: Extra Segment + 7c37: 8e c0 mov %eax,%es + movw %ax, %ss # -> SS: Stack Segment + 7c39: 8e d0 mov %eax,%ss + movw $0, %ax # Zero segments not ready for use + 7c3b: 66 b8 00 00 mov $0x0,%ax + movw %ax, %fs # -> FS + 7c3f: 8e e0 mov %eax,%fs + movw %ax, %gs # -> GS + 7c41: 8e e8 mov %eax,%gs + + # Set up the stack pointer and call into C. + movl $start, %esp + 7c43: bc 00 7c 00 00 mov $0x7c00,%esp + call bootmain + 7c48: e8 e0 00 00 00 call 7d2d + +00007c4d : + + # If bootmain returns (it shouldn't), loop. +spin: + jmp spin + 7c4d: eb fe jmp 7c4d + 7c4f: 90 nop + +00007c50 : + ... + 7c58: ff (bad) + 7c59: ff 00 incl (%eax) + 7c5b: 00 00 add %al,(%eax) + 7c5d: 9a cf 00 ff ff 00 00 lcall $0x0,$0xffff00cf + 7c64: 00 .byte 0x0 + 7c65: 92 xchg %eax,%edx + 7c66: cf iret + ... + +00007c68 : + 7c68: 17 pop %ss + 7c69: 00 50 7c add %dl,0x7c(%eax) + ... + +00007c6e : +// Routines to let C code use special x86 instructions. + +static inline uchar inb(ushort port) { + uchar data; + + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); + 7c6e: ba f7 01 00 00 mov $0x1f7,%edx + 7c73: ec in (%dx),%al + entry(); +} + +void waitdisk(void) { + // Wait for disk ready. + while ((inb(0x1F7) & 0xC0) != 0x40) { + 7c74: 83 e0 c0 and $0xffffffc0,%eax + 7c77: 3c 40 cmp $0x40,%al + 7c79: 75 f8 jne 7c73 + ; + } +} + 7c7b: c3 ret + +00007c7c : + +// Read a single sector at offset into dst. +void readsect(void *dst, uint offset) { + 7c7c: 55 push %ebp + 7c7d: 89 e5 mov %esp,%ebp + 7c7f: 57 push %edi + 7c80: 53 push %ebx + 7c81: 8b 5d 0c mov 0xc(%ebp),%ebx + // Issue command. + waitdisk(); + 7c84: e8 e5 ff ff ff call 7c6e + "d" (port), "0" (addr), "1" (cnt) : + "memory", "cc"); +} + +static inline void outb(ushort port, uchar data) { + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); + 7c89: b8 01 00 00 00 mov $0x1,%eax + 7c8e: ba f2 01 00 00 mov $0x1f2,%edx + 7c93: ee out %al,(%dx) + 7c94: ba f3 01 00 00 mov $0x1f3,%edx + 7c99: 89 d8 mov %ebx,%eax + 7c9b: ee out %al,(%dx) + outb(0x1F2, 1); // count = 1 + outb(0x1F3, offset); + outb(0x1F4, offset >> 8); + 7c9c: 89 d8 mov %ebx,%eax + 7c9e: c1 e8 08 shr $0x8,%eax + 7ca1: ba f4 01 00 00 mov $0x1f4,%edx + 7ca6: ee out %al,(%dx) + outb(0x1F5, offset >> 16); + 7ca7: 89 d8 mov %ebx,%eax + 7ca9: c1 e8 10 shr $0x10,%eax + 7cac: ba f5 01 00 00 mov $0x1f5,%edx + 7cb1: ee out %al,(%dx) + outb(0x1F6, (offset >> 24) | 0xE0); + 7cb2: 89 d8 mov %ebx,%eax + 7cb4: c1 e8 18 shr $0x18,%eax + 7cb7: 83 c8 e0 or $0xffffffe0,%eax + 7cba: ba f6 01 00 00 mov $0x1f6,%edx + 7cbf: ee out %al,(%dx) + 7cc0: b8 20 00 00 00 mov $0x20,%eax + 7cc5: ba f7 01 00 00 mov $0x1f7,%edx + 7cca: ee out %al,(%dx) + outb(0x1F7, 0x20); // cmd 0x20 - read sectors + + // Read data. + waitdisk(); + 7ccb: e8 9e ff ff ff call 7c6e + asm volatile ("cld; rep insl" : + 7cd0: 8b 7d 08 mov 0x8(%ebp),%edi + 7cd3: b9 80 00 00 00 mov $0x80,%ecx + 7cd8: ba f0 01 00 00 mov $0x1f0,%edx + 7cdd: fc cld + 7cde: f3 6d rep insl (%dx),%es:(%edi) + insl(0x1F0, dst, SECTSIZE / 4); +} + 7ce0: 5b pop %ebx + 7ce1: 5f pop %edi + 7ce2: 5d pop %ebp + 7ce3: c3 ret + +00007ce4 : + +// Read 'count' bytes at 'offset' from kernel into physical address 'pa'. +// Might copy more than asked. + +void readseg(uchar* pa, uint count, uint offset) { + 7ce4: 55 push %ebp + 7ce5: 89 e5 mov %esp,%ebp + 7ce7: 57 push %edi + 7ce8: 56 push %esi + 7ce9: 53 push %ebx + 7cea: 83 ec 0c sub $0xc,%esp + 7ced: 8b 5d 08 mov 0x8(%ebp),%ebx + 7cf0: 8b 75 10 mov 0x10(%ebp),%esi + uchar* epa; + + epa = pa + count; + 7cf3: 89 df mov %ebx,%edi + 7cf5: 03 7d 0c add 0xc(%ebp),%edi + + // Round down to sector boundary. + pa -= offset % SECTSIZE; + 7cf8: 89 f0 mov %esi,%eax + 7cfa: 25 ff 01 00 00 and $0x1ff,%eax + 7cff: 29 c3 sub %eax,%ebx + + // Translate from bytes to sectors; kernel starts at sector 1. + offset = (offset / SECTSIZE) + 1; + 7d01: c1 ee 09 shr $0x9,%esi + 7d04: 83 c6 01 add $0x1,%esi + + // If this is too slow, we could read lots of sectors at a time. + // We'd write more to memory than asked, but it doesn't matter -- + // we load in increasing order. + for (; pa < epa; pa += SECTSIZE, offset++) { + 7d07: 39 df cmp %ebx,%edi + 7d09: 76 1a jbe 7d25 + readsect(pa, offset); + 7d0b: 83 ec 08 sub $0x8,%esp + 7d0e: 56 push %esi + 7d0f: 53 push %ebx + 7d10: e8 67 ff ff ff call 7c7c + for (; pa < epa; pa += SECTSIZE, offset++) { + 7d15: 81 c3 00 02 00 00 add $0x200,%ebx + 7d1b: 83 c6 01 add $0x1,%esi + 7d1e: 83 c4 10 add $0x10,%esp + 7d21: 39 df cmp %ebx,%edi + 7d23: 77 e6 ja 7d0b + } +} + 7d25: 8d 65 f4 lea -0xc(%ebp),%esp + 7d28: 5b pop %ebx + 7d29: 5e pop %esi + 7d2a: 5f pop %edi + 7d2b: 5d pop %ebp + 7d2c: c3 ret + +00007d2d : +void bootmain(void) { + 7d2d: 55 push %ebp + 7d2e: 89 e5 mov %esp,%ebp + 7d30: 57 push %edi + 7d31: 56 push %esi + 7d32: 53 push %ebx + 7d33: 83 ec 10 sub $0x10,%esp + readseg((uchar*)elf, 4096, 0); + 7d36: 6a 00 push $0x0 + 7d38: 68 00 10 00 00 push $0x1000 + 7d3d: 68 00 00 01 00 push $0x10000 + 7d42: e8 9d ff ff ff call 7ce4 + if (elf->magic != ELF_MAGIC) { + 7d47: 83 c4 10 add $0x10,%esp + 7d4a: 81 3d 00 00 01 00 7f cmpl $0x464c457f,0x10000 + 7d51: 45 4c 46 + 7d54: 75 21 jne 7d77 + ph = (struct proghdr*)((uchar*)elf + elf->phoff); + 7d56: a1 1c 00 01 00 mov 0x1001c,%eax + 7d5b: 8d 98 00 00 01 00 lea 0x10000(%eax),%ebx + eph = ph + elf->phnum; + 7d61: 0f b7 35 2c 00 01 00 movzwl 0x1002c,%esi + 7d68: c1 e6 05 shl $0x5,%esi + 7d6b: 01 de add %ebx,%esi + for (; ph < eph; ph++) { + 7d6d: 39 f3 cmp %esi,%ebx + 7d6f: 72 15 jb 7d86 + entry(); + 7d71: ff 15 18 00 01 00 call *0x10018 +} + 7d77: 8d 65 f4 lea -0xc(%ebp),%esp + 7d7a: 5b pop %ebx + 7d7b: 5e pop %esi + 7d7c: 5f pop %edi + 7d7d: 5d pop %ebp + 7d7e: c3 ret + for (; ph < eph; ph++) { + 7d7f: 83 c3 20 add $0x20,%ebx + 7d82: 39 de cmp %ebx,%esi + 7d84: 76 eb jbe 7d71 + pa = (uchar*)ph->paddr; + 7d86: 8b 7b 0c mov 0xc(%ebx),%edi + readseg(pa, ph->filesz, ph->off); + 7d89: 83 ec 04 sub $0x4,%esp + 7d8c: ff 73 04 push 0x4(%ebx) + 7d8f: ff 73 10 push 0x10(%ebx) + 7d92: 57 push %edi + 7d93: e8 4c ff ff ff call 7ce4 + if (ph->memsz > ph->filesz) { + 7d98: 8b 4b 14 mov 0x14(%ebx),%ecx + 7d9b: 8b 43 10 mov 0x10(%ebx),%eax + 7d9e: 83 c4 10 add $0x10,%esp + 7da1: 39 c1 cmp %eax,%ecx + 7da3: 76 da jbe 7d7f + stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz); + 7da5: 01 c7 add %eax,%edi + 7da7: 29 c1 sub %eax,%ecx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 7da9: b8 00 00 00 00 mov $0x0,%eax + 7dae: fc cld + 7daf: f3 aa rep stos %al,%es:(%edi) + "=D" (addr), "=c" (cnt) : + "0" (addr), "1" (cnt), "a" (data) : + "memory", "cc"); +} + 7db1: eb cc jmp 7d7f diff --git a/bootblock.o b/bootblock.o new file mode 100644 index 0000000..485cd59 Binary files /dev/null and b/bootblock.o differ diff --git a/bootblockother.o b/bootblockother.o new file mode 100644 index 0000000..83514b1 Binary files /dev/null and b/bootblockother.o differ diff --git a/bootmain.c b/bootmain.c new file mode 100644 index 0000000..7efd295 --- /dev/null +++ b/bootmain.c @@ -0,0 +1,93 @@ +// Boot loader. +// +// Part of the boot block, along with bootasm.S, which calls bootmain(). +// bootasm.S has put the processor into protected 32-bit mode. +// bootmain() loads an ELF kernel image from the disk starting at +// sector 1 and then jumps to the kernel entry routine. + +#include "types.h" +#include "elf.h" +#include "x86.h" +#include "memlayout.h" + +#define SECTSIZE 512 + +void readseg(uchar*, uint, uint); + +void bootmain(void) { + struct elfhdr *elf; + struct proghdr *ph, *eph; + void (*entry)(void); + uchar* pa; + + elf = (struct elfhdr*)0x10000; // scratch space + + // Read 1st page off disk + readseg((uchar*)elf, 4096, 0); + + // Is this an ELF executable? + if (elf->magic != ELF_MAGIC) { + return; // let bootasm.S handle error + + } + // Load each program segment (ignores ph flags). + ph = (struct proghdr*)((uchar*)elf + elf->phoff); + eph = ph + elf->phnum; + for (; ph < eph; ph++) { + pa = (uchar*)ph->paddr; + readseg(pa, ph->filesz, ph->off); + if (ph->memsz > ph->filesz) { + stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz); + } + } + + // Call the entry point from the ELF header. + // Does not return! + entry = (void (*)(void))(elf->entry); + entry(); +} + +void waitdisk(void) { + // Wait for disk ready. + while ((inb(0x1F7) & 0xC0) != 0x40) { + ; + } +} + +// Read a single sector at offset into dst. +void readsect(void *dst, uint offset) { + // Issue command. + waitdisk(); + outb(0x1F2, 1); // count = 1 + outb(0x1F3, offset); + outb(0x1F4, offset >> 8); + outb(0x1F5, offset >> 16); + outb(0x1F6, (offset >> 24) | 0xE0); + outb(0x1F7, 0x20); // cmd 0x20 - read sectors + + // Read data. + waitdisk(); + insl(0x1F0, dst, SECTSIZE / 4); +} + +// Read 'count' bytes at 'offset' from kernel into physical address 'pa'. +// Might copy more than asked. + +void readseg(uchar* pa, uint count, uint offset) { + uchar* epa; + + epa = pa + count; + + // Round down to sector boundary. + pa -= offset % SECTSIZE; + + // Translate from bytes to sectors; kernel starts at sector 1. + offset = (offset / SECTSIZE) + 1; + + // If this is too slow, we could read lots of sectors at a time. + // We'd write more to memory than asked, but it doesn't matter -- + // we load in increasing order. + for (; pa < epa; pa += SECTSIZE, offset++) { + readsect(pa, offset); + } +} diff --git a/bootmain.d b/bootmain.d new file mode 100644 index 0000000..b32eaf5 --- /dev/null +++ b/bootmain.d @@ -0,0 +1 @@ +bootmain.o: bootmain.c types.h elf.h x86.h memlayout.h diff --git a/bootmain.o b/bootmain.o new file mode 100644 index 0000000..0734b91 Binary files /dev/null and b/bootmain.o differ diff --git a/buf.h b/buf.h new file mode 100644 index 0000000..d5d8d4d --- /dev/null +++ b/buf.h @@ -0,0 +1,14 @@ +struct buf { + int flags; + uint dev; + uint blockno; + struct sleeplock lock; + uint refcnt; + struct buf *prev; // LRU cache list + struct buf *next; + struct buf *qnext; // disk queue + uchar data[BSIZE]; +}; +#define B_VALID 0x2 // buffer has been read from disk +#define B_DIRTY 0x4 // buffer needs to be written to disk + diff --git a/cat.asm b/cat.asm new file mode 100644 index 0000000..014fa56 --- /dev/null +++ b/cat.asm @@ -0,0 +1,1256 @@ + +_cat: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: + printf(1, "cat: read error\n"); + exit(); + } +} + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: be 01 00 00 00 mov $0x1,%esi + 14: 53 push %ebx + 15: 51 push %ecx + 16: 83 ec 18 sub $0x18,%esp + 19: 8b 01 mov (%ecx),%eax + 1b: 8b 59 04 mov 0x4(%ecx),%ebx + 1e: 89 45 e4 mov %eax,-0x1c(%ebp) + 21: 83 c3 04 add $0x4,%ebx + int fd, i; + + if (argc <= 1) { + 24: 83 f8 01 cmp $0x1,%eax + 27: 7e 54 jle 7d + 29: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + cat(0); + exit(); + } + + for (i = 1; i < argc; i++) { + if ((fd = open(argv[i], 0)) < 0) { + 30: 83 ec 08 sub $0x8,%esp + 33: 6a 00 push $0x0 + 35: ff 33 push (%ebx) + 37: e8 8f 03 00 00 call 3cb + 3c: 83 c4 10 add $0x10,%esp + 3f: 89 c7 mov %eax,%edi + 41: 85 c0 test %eax,%eax + 43: 78 24 js 69 + printf(1, "cat: cannot open %s\n", argv[i]); + exit(); + } + cat(fd); + 45: 83 ec 0c sub $0xc,%esp + for (i = 1; i < argc; i++) { + 48: 83 c6 01 add $0x1,%esi + 4b: 83 c3 04 add $0x4,%ebx + cat(fd); + 4e: 50 push %eax + 4f: e8 3c 00 00 00 call 90 + close(fd); + 54: 89 3c 24 mov %edi,(%esp) + 57: e8 9f 03 00 00 call 3fb + for (i = 1; i < argc; i++) { + 5c: 83 c4 10 add $0x10,%esp + 5f: 39 75 e4 cmp %esi,-0x1c(%ebp) + 62: 75 cc jne 30 + } + exit(); + 64: e8 fa 02 00 00 call 363 + printf(1, "cat: cannot open %s\n", argv[i]); + 69: 50 push %eax + 6a: ff 33 push (%ebx) + 6c: 68 1b 08 00 00 push $0x81b + 71: 6a 01 push $0x1 + 73: e8 58 04 00 00 call 4d0 + exit(); + 78: e8 e6 02 00 00 call 363 + cat(0); + 7d: 83 ec 0c sub $0xc,%esp + 80: 6a 00 push $0x0 + 82: e8 09 00 00 00 call 90 + exit(); + 87: e8 d7 02 00 00 call 363 + 8c: 66 90 xchg %ax,%ax + 8e: 66 90 xchg %ax,%ax + +00000090 : +void cat(int fd) { + 90: 55 push %ebp + 91: 89 e5 mov %esp,%ebp + 93: 56 push %esi + 94: 8b 75 08 mov 0x8(%ebp),%esi + 97: 53 push %ebx + while ((n = read(fd, buf, sizeof(buf))) > 0) { + 98: eb 1d jmp b7 + 9a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (write(1, buf, n) != n) { + a0: 83 ec 04 sub $0x4,%esp + a3: 53 push %ebx + a4: 68 80 0b 00 00 push $0xb80 + a9: 6a 01 push $0x1 + ab: e8 23 03 00 00 call 3d3 + b0: 83 c4 10 add $0x10,%esp + b3: 39 d8 cmp %ebx,%eax + b5: 75 25 jne dc + while ((n = read(fd, buf, sizeof(buf))) > 0) { + b7: 83 ec 04 sub $0x4,%esp + ba: 68 00 02 00 00 push $0x200 + bf: 68 80 0b 00 00 push $0xb80 + c4: 56 push %esi + c5: e8 b1 02 00 00 call 37b + ca: 83 c4 10 add $0x10,%esp + cd: 89 c3 mov %eax,%ebx + cf: 85 c0 test %eax,%eax + d1: 7f cd jg a0 + if (n < 0) { + d3: 75 1b jne f0 +} + d5: 8d 65 f8 lea -0x8(%ebp),%esp + d8: 5b pop %ebx + d9: 5e pop %esi + da: 5d pop %ebp + db: c3 ret + printf(1, "cat: write error\n"); + dc: 83 ec 08 sub $0x8,%esp + df: 68 f8 07 00 00 push $0x7f8 + e4: 6a 01 push $0x1 + e6: e8 e5 03 00 00 call 4d0 + exit(); + eb: e8 73 02 00 00 call 363 + printf(1, "cat: read error\n"); + f0: 50 push %eax + f1: 50 push %eax + f2: 68 0a 08 00 00 push $0x80a + f7: 6a 01 push $0x1 + f9: e8 d2 03 00 00 call 4d0 + exit(); + fe: e8 60 02 00 00 call 363 + 103: 66 90 xchg %ax,%ax + 105: 66 90 xchg %ax,%ax + 107: 66 90 xchg %ax,%ax + 109: 66 90 xchg %ax,%ax + 10b: 66 90 xchg %ax,%ax + 10d: 66 90 xchg %ax,%ax + 10f: 90 nop + +00000110 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 110: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 111: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 113: 89 e5 mov %esp,%ebp + 115: 53 push %ebx + 116: 8b 4d 08 mov 0x8(%ebp),%ecx + 119: 8b 5d 0c mov 0xc(%ebp),%ebx + 11c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 120: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 124: 88 14 01 mov %dl,(%ecx,%eax,1) + 127: 83 c0 01 add $0x1,%eax + 12a: 84 d2 test %dl,%dl + 12c: 75 f2 jne 120 + ; + } + return os; +} + 12e: 8b 5d fc mov -0x4(%ebp),%ebx + 131: 89 c8 mov %ecx,%eax + 133: c9 leave + 134: c3 ret + 135: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 13c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000140 : + +int strcmp(const char *p, const char *q) { + 140: 55 push %ebp + 141: 89 e5 mov %esp,%ebp + 143: 53 push %ebx + 144: 8b 55 08 mov 0x8(%ebp),%edx + 147: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 14a: 0f b6 02 movzbl (%edx),%eax + 14d: 84 c0 test %al,%al + 14f: 75 17 jne 168 + 151: eb 3a jmp 18d + 153: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 157: 90 nop + 158: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 15c: 83 c2 01 add $0x1,%edx + 15f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 162: 84 c0 test %al,%al + 164: 74 1a je 180 + p++, q++; + 166: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 168: 0f b6 19 movzbl (%ecx),%ebx + 16b: 38 c3 cmp %al,%bl + 16d: 74 e9 je 158 + } + return (uchar) * p - (uchar) * q; + 16f: 29 d8 sub %ebx,%eax +} + 171: 8b 5d fc mov -0x4(%ebp),%ebx + 174: c9 leave + 175: c3 ret + 176: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 17d: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 180: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 184: 31 c0 xor %eax,%eax + 186: 29 d8 sub %ebx,%eax +} + 188: 8b 5d fc mov -0x4(%ebp),%ebx + 18b: c9 leave + 18c: c3 ret + return (uchar) * p - (uchar) * q; + 18d: 0f b6 19 movzbl (%ecx),%ebx + 190: 31 c0 xor %eax,%eax + 192: eb db jmp 16f + 194: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 19b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 19f: 90 nop + +000001a0 : + +uint strlen(const char *s) { + 1a0: 55 push %ebp + 1a1: 89 e5 mov %esp,%ebp + 1a3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 1a6: 80 3a 00 cmpb $0x0,(%edx) + 1a9: 74 15 je 1c0 + 1ab: 31 c0 xor %eax,%eax + 1ad: 8d 76 00 lea 0x0(%esi),%esi + 1b0: 83 c0 01 add $0x1,%eax + 1b3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 1b7: 89 c1 mov %eax,%ecx + 1b9: 75 f5 jne 1b0 + ; + } + return n; +} + 1bb: 89 c8 mov %ecx,%eax + 1bd: 5d pop %ebp + 1be: c3 ret + 1bf: 90 nop + for (n = 0; s[n]; n++) { + 1c0: 31 c9 xor %ecx,%ecx +} + 1c2: 5d pop %ebp + 1c3: 89 c8 mov %ecx,%eax + 1c5: c3 ret + 1c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1cd: 8d 76 00 lea 0x0(%esi),%esi + +000001d0 : + +void* memset(void *dst, int c, uint n) { + 1d0: 55 push %ebp + 1d1: 89 e5 mov %esp,%ebp + 1d3: 57 push %edi + 1d4: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 1d7: 8b 4d 10 mov 0x10(%ebp),%ecx + 1da: 8b 45 0c mov 0xc(%ebp),%eax + 1dd: 89 d7 mov %edx,%edi + 1df: fc cld + 1e0: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 1e2: 8b 7d fc mov -0x4(%ebp),%edi + 1e5: 89 d0 mov %edx,%eax + 1e7: c9 leave + 1e8: c3 ret + 1e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +000001f0 : + +char* strchr(const char *s, char c) { + 1f0: 55 push %ebp + 1f1: 89 e5 mov %esp,%ebp + 1f3: 8b 45 08 mov 0x8(%ebp),%eax + 1f6: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 1fa: 0f b6 10 movzbl (%eax),%edx + 1fd: 84 d2 test %dl,%dl + 1ff: 75 12 jne 213 + 201: eb 1d jmp 220 + 203: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 207: 90 nop + 208: 0f b6 50 01 movzbl 0x1(%eax),%edx + 20c: 83 c0 01 add $0x1,%eax + 20f: 84 d2 test %dl,%dl + 211: 74 0d je 220 + if (*s == c) { + 213: 38 d1 cmp %dl,%cl + 215: 75 f1 jne 208 + return (char*)s; + } + } + return 0; +} + 217: 5d pop %ebp + 218: c3 ret + 219: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 220: 31 c0 xor %eax,%eax +} + 222: 5d pop %ebp + 223: c3 ret + 224: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 22b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 22f: 90 nop + +00000230 : + +char* gets(char *buf, int max) { + 230: 55 push %ebp + 231: 89 e5 mov %esp,%ebp + 233: 57 push %edi + 234: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 235: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 238: 53 push %ebx + for (i = 0; i + 1 < max;) { + 239: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 23b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 23e: eb 27 jmp 267 + cc = read(0, &c, 1); + 240: 83 ec 04 sub $0x4,%esp + 243: 6a 01 push $0x1 + 245: 57 push %edi + 246: 6a 00 push $0x0 + 248: e8 2e 01 00 00 call 37b + if (cc < 1) { + 24d: 83 c4 10 add $0x10,%esp + 250: 85 c0 test %eax,%eax + 252: 7e 1d jle 271 + break; + } + buf[i++] = c; + 254: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 258: 8b 55 08 mov 0x8(%ebp),%edx + 25b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 25f: 3c 0a cmp $0xa,%al + 261: 74 1d je 280 + 263: 3c 0d cmp $0xd,%al + 265: 74 19 je 280 + for (i = 0; i + 1 < max;) { + 267: 89 de mov %ebx,%esi + 269: 83 c3 01 add $0x1,%ebx + 26c: 3b 5d 0c cmp 0xc(%ebp),%ebx + 26f: 7c cf jl 240 + break; + } + } + buf[i] = '\0'; + 271: 8b 45 08 mov 0x8(%ebp),%eax + 274: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 278: 8d 65 f4 lea -0xc(%ebp),%esp + 27b: 5b pop %ebx + 27c: 5e pop %esi + 27d: 5f pop %edi + 27e: 5d pop %ebp + 27f: c3 ret + buf[i] = '\0'; + 280: 8b 45 08 mov 0x8(%ebp),%eax + 283: 89 de mov %ebx,%esi + 285: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 289: 8d 65 f4 lea -0xc(%ebp),%esp + 28c: 5b pop %ebx + 28d: 5e pop %esi + 28e: 5f pop %edi + 28f: 5d pop %ebp + 290: c3 ret + 291: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 298: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 29f: 90 nop + +000002a0 : + +int stat(const char *n, struct stat *st) { + 2a0: 55 push %ebp + 2a1: 89 e5 mov %esp,%ebp + 2a3: 56 push %esi + 2a4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 2a5: 83 ec 08 sub $0x8,%esp + 2a8: 6a 00 push $0x0 + 2aa: ff 75 08 push 0x8(%ebp) + 2ad: e8 19 01 00 00 call 3cb + if (fd < 0) { + 2b2: 83 c4 10 add $0x10,%esp + 2b5: 85 c0 test %eax,%eax + 2b7: 78 27 js 2e0 + return -1; + } + r = fstat(fd, st); + 2b9: 83 ec 08 sub $0x8,%esp + 2bc: ff 75 0c push 0xc(%ebp) + 2bf: 89 c3 mov %eax,%ebx + 2c1: 50 push %eax + 2c2: e8 cc 00 00 00 call 393 + close(fd); + 2c7: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 2ca: 89 c6 mov %eax,%esi + close(fd); + 2cc: e8 2a 01 00 00 call 3fb + return r; + 2d1: 83 c4 10 add $0x10,%esp +} + 2d4: 8d 65 f8 lea -0x8(%ebp),%esp + 2d7: 89 f0 mov %esi,%eax + 2d9: 5b pop %ebx + 2da: 5e pop %esi + 2db: 5d pop %ebp + 2dc: c3 ret + 2dd: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 2e0: be ff ff ff ff mov $0xffffffff,%esi + 2e5: eb ed jmp 2d4 + 2e7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2ee: 66 90 xchg %ax,%ax + +000002f0 : + +int atoi(const char *s) { + 2f0: 55 push %ebp + 2f1: 89 e5 mov %esp,%ebp + 2f3: 53 push %ebx + 2f4: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 2f7: 0f be 02 movsbl (%edx),%eax + 2fa: 8d 48 d0 lea -0x30(%eax),%ecx + 2fd: 80 f9 09 cmp $0x9,%cl + n = 0; + 300: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 305: 77 1e ja 325 + 307: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 30e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 310: 83 c2 01 add $0x1,%edx + 313: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 316: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 31a: 0f be 02 movsbl (%edx),%eax + 31d: 8d 58 d0 lea -0x30(%eax),%ebx + 320: 80 fb 09 cmp $0x9,%bl + 323: 76 eb jbe 310 + } + return n; +} + 325: 8b 5d fc mov -0x4(%ebp),%ebx + 328: 89 c8 mov %ecx,%eax + 32a: c9 leave + 32b: c3 ret + 32c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000330 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 330: 55 push %ebp + 331: 89 e5 mov %esp,%ebp + 333: 57 push %edi + 334: 8b 45 10 mov 0x10(%ebp),%eax + 337: 8b 55 08 mov 0x8(%ebp),%edx + 33a: 56 push %esi + 33b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 33e: 85 c0 test %eax,%eax + 340: 7e 13 jle 355 + 342: 01 d0 add %edx,%eax + dst = vdst; + 344: 89 d7 mov %edx,%edi + 346: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 34d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 350: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 351: 39 f8 cmp %edi,%eax + 353: 75 fb jne 350 + } + return vdst; +} + 355: 5e pop %esi + 356: 89 d0 mov %edx,%eax + 358: 5f pop %edi + 359: 5d pop %ebp + 35a: c3 ret + +0000035b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 35b: b8 01 00 00 00 mov $0x1,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(exit) + 363: b8 02 00 00 00 mov $0x2,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + +0000036b : +SYSCALL(wait) + 36b: b8 03 00 00 00 mov $0x3,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(pipe) + 373: b8 04 00 00 00 mov $0x4,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + +0000037b : +SYSCALL(read) + 37b: b8 05 00 00 00 mov $0x5,%eax + 380: cd 40 int $0x40 + 382: c3 ret + +00000383 : +SYSCALL(kill) + 383: b8 06 00 00 00 mov $0x6,%eax + 388: cd 40 int $0x40 + 38a: c3 ret + +0000038b : +SYSCALL(exec) + 38b: b8 07 00 00 00 mov $0x7,%eax + 390: cd 40 int $0x40 + 392: c3 ret + +00000393 : +SYSCALL(fstat) + 393: b8 08 00 00 00 mov $0x8,%eax + 398: cd 40 int $0x40 + 39a: c3 ret + +0000039b : +SYSCALL(chdir) + 39b: b8 09 00 00 00 mov $0x9,%eax + 3a0: cd 40 int $0x40 + 3a2: c3 ret + +000003a3 : +SYSCALL(dup) + 3a3: b8 0a 00 00 00 mov $0xa,%eax + 3a8: cd 40 int $0x40 + 3aa: c3 ret + +000003ab : +SYSCALL(getpid) + 3ab: b8 0b 00 00 00 mov $0xb,%eax + 3b0: cd 40 int $0x40 + 3b2: c3 ret + +000003b3 : +SYSCALL(sbrk) + 3b3: b8 0c 00 00 00 mov $0xc,%eax + 3b8: cd 40 int $0x40 + 3ba: c3 ret + +000003bb : +SYSCALL(sleep) + 3bb: b8 0d 00 00 00 mov $0xd,%eax + 3c0: cd 40 int $0x40 + 3c2: c3 ret + +000003c3 : +SYSCALL(uptime) + 3c3: b8 0e 00 00 00 mov $0xe,%eax + 3c8: cd 40 int $0x40 + 3ca: c3 ret + +000003cb : +SYSCALL(open) + 3cb: b8 0f 00 00 00 mov $0xf,%eax + 3d0: cd 40 int $0x40 + 3d2: c3 ret + +000003d3 : +SYSCALL(write) + 3d3: b8 10 00 00 00 mov $0x10,%eax + 3d8: cd 40 int $0x40 + 3da: c3 ret + +000003db : +SYSCALL(mknod) + 3db: b8 11 00 00 00 mov $0x11,%eax + 3e0: cd 40 int $0x40 + 3e2: c3 ret + +000003e3 : +SYSCALL(unlink) + 3e3: b8 12 00 00 00 mov $0x12,%eax + 3e8: cd 40 int $0x40 + 3ea: c3 ret + +000003eb : +SYSCALL(link) + 3eb: b8 13 00 00 00 mov $0x13,%eax + 3f0: cd 40 int $0x40 + 3f2: c3 ret + +000003f3 : +SYSCALL(mkdir) + 3f3: b8 14 00 00 00 mov $0x14,%eax + 3f8: cd 40 int $0x40 + 3fa: c3 ret + +000003fb : +SYSCALL(close) + 3fb: b8 15 00 00 00 mov $0x15,%eax + 400: cd 40 int $0x40 + 402: c3 ret + +00000403 : +SYSCALL(getch) + 403: b8 16 00 00 00 mov $0x16,%eax + 408: cd 40 int $0x40 + 40a: c3 ret + +0000040b : +SYSCALL(greeting) + 40b: b8 17 00 00 00 mov $0x17,%eax + 410: cd 40 int $0x40 + 412: c3 ret + +00000413 : +SYSCALL(shutdown) + 413: b8 18 00 00 00 mov $0x18,%eax + 418: cd 40 int $0x40 + 41a: c3 ret + 41b: 66 90 xchg %ax,%ax + 41d: 66 90 xchg %ax,%ax + 41f: 90 nop + +00000420 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 420: 55 push %ebp + 421: 89 e5 mov %esp,%ebp + 423: 57 push %edi + 424: 56 push %esi + 425: 53 push %ebx + 426: 83 ec 3c sub $0x3c,%esp + 429: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 42c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 42e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 431: 85 d2 test %edx,%edx + 433: 0f 89 7f 00 00 00 jns 4b8 + 439: f6 45 08 01 testb $0x1,0x8(%ebp) + 43d: 74 79 je 4b8 + neg = 1; + 43f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 446: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 448: 31 db xor %ebx,%ebx + 44a: 8d 75 d7 lea -0x29(%ebp),%esi + 44d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 450: 89 c8 mov %ecx,%eax + 452: 31 d2 xor %edx,%edx + 454: 89 cf mov %ecx,%edi + 456: f7 75 c4 divl -0x3c(%ebp) + 459: 0f b6 92 90 08 00 00 movzbl 0x890(%edx),%edx + 460: 89 45 c0 mov %eax,-0x40(%ebp) + 463: 89 d8 mov %ebx,%eax + 465: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 468: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 46b: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 46e: 39 7d c4 cmp %edi,-0x3c(%ebp) + 471: 76 dd jbe 450 + if (neg) { + 473: 8b 4d bc mov -0x44(%ebp),%ecx + 476: 85 c9 test %ecx,%ecx + 478: 74 0c je 486 + buf[i++] = '-'; + 47a: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 47f: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 481: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 486: 8b 7d b8 mov -0x48(%ebp),%edi + 489: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 48d: eb 07 jmp 496 + 48f: 90 nop + putc(fd, buf[i]); + 490: 0f b6 13 movzbl (%ebx),%edx + 493: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 496: 83 ec 04 sub $0x4,%esp + 499: 88 55 d7 mov %dl,-0x29(%ebp) + 49c: 6a 01 push $0x1 + 49e: 56 push %esi + 49f: 57 push %edi + 4a0: e8 2e ff ff ff call 3d3 + while (--i >= 0) { + 4a5: 83 c4 10 add $0x10,%esp + 4a8: 39 de cmp %ebx,%esi + 4aa: 75 e4 jne 490 + } +} + 4ac: 8d 65 f4 lea -0xc(%ebp),%esp + 4af: 5b pop %ebx + 4b0: 5e pop %esi + 4b1: 5f pop %edi + 4b2: 5d pop %ebp + 4b3: c3 ret + 4b4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 4b8: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 4bf: eb 87 jmp 448 + 4c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4cf: 90 nop + +000004d0 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 4d0: 55 push %ebp + 4d1: 89 e5 mov %esp,%ebp + 4d3: 57 push %edi + 4d4: 56 push %esi + 4d5: 53 push %ebx + 4d6: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 4d9: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 4dc: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 4df: 0f b6 13 movzbl (%ebx),%edx + 4e2: 84 d2 test %dl,%dl + 4e4: 74 6a je 550 + ap = (uint*)(void*)&fmt + 1; + 4e6: 8d 45 10 lea 0x10(%ebp),%eax + 4e9: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 4ec: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 4ef: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 4f1: 89 45 d0 mov %eax,-0x30(%ebp) + 4f4: eb 36 jmp 52c + 4f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4fd: 8d 76 00 lea 0x0(%esi),%esi + 500: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 503: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 508: 83 f8 25 cmp $0x25,%eax + 50b: 74 15 je 522 + write(fd, &c, 1); + 50d: 83 ec 04 sub $0x4,%esp + 510: 88 55 e7 mov %dl,-0x19(%ebp) + 513: 6a 01 push $0x1 + 515: 57 push %edi + 516: 56 push %esi + 517: e8 b7 fe ff ff call 3d3 + 51c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 51f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 522: 0f b6 13 movzbl (%ebx),%edx + 525: 83 c3 01 add $0x1,%ebx + 528: 84 d2 test %dl,%dl + 52a: 74 24 je 550 + c = fmt[i] & 0xff; + 52c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 52f: 85 c9 test %ecx,%ecx + 531: 74 cd je 500 + } + } + else if (state == '%') { + 533: 83 f9 25 cmp $0x25,%ecx + 536: 75 ea jne 522 + if (c == 'd') { + 538: 83 f8 25 cmp $0x25,%eax + 53b: 0f 84 07 01 00 00 je 648 + 541: 83 e8 63 sub $0x63,%eax + 544: 83 f8 15 cmp $0x15,%eax + 547: 77 17 ja 560 + 549: ff 24 85 38 08 00 00 jmp *0x838(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 550: 8d 65 f4 lea -0xc(%ebp),%esp + 553: 5b pop %ebx + 554: 5e pop %esi + 555: 5f pop %edi + 556: 5d pop %ebp + 557: c3 ret + 558: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 55f: 90 nop + write(fd, &c, 1); + 560: 83 ec 04 sub $0x4,%esp + 563: 88 55 d4 mov %dl,-0x2c(%ebp) + 566: 6a 01 push $0x1 + 568: 57 push %edi + 569: 56 push %esi + 56a: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 56e: e8 60 fe ff ff call 3d3 + putc(fd, c); + 573: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 577: 83 c4 0c add $0xc,%esp + 57a: 88 55 e7 mov %dl,-0x19(%ebp) + 57d: 6a 01 push $0x1 + 57f: 57 push %edi + 580: 56 push %esi + 581: e8 4d fe ff ff call 3d3 + putc(fd, c); + 586: 83 c4 10 add $0x10,%esp + state = 0; + 589: 31 c9 xor %ecx,%ecx + 58b: eb 95 jmp 522 + 58d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 590: 83 ec 0c sub $0xc,%esp + 593: b9 10 00 00 00 mov $0x10,%ecx + 598: 6a 00 push $0x0 + 59a: 8b 45 d0 mov -0x30(%ebp),%eax + 59d: 8b 10 mov (%eax),%edx + 59f: 89 f0 mov %esi,%eax + 5a1: e8 7a fe ff ff call 420 + ap++; + 5a6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 5aa: 83 c4 10 add $0x10,%esp + state = 0; + 5ad: 31 c9 xor %ecx,%ecx + 5af: e9 6e ff ff ff jmp 522 + 5b4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 5b8: 8b 45 d0 mov -0x30(%ebp),%eax + 5bb: 8b 10 mov (%eax),%edx + ap++; + 5bd: 83 c0 04 add $0x4,%eax + 5c0: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 5c3: 85 d2 test %edx,%edx + 5c5: 0f 84 8d 00 00 00 je 658 + while (*s != 0) { + 5cb: 0f b6 02 movzbl (%edx),%eax + state = 0; + 5ce: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 5d0: 84 c0 test %al,%al + 5d2: 0f 84 4a ff ff ff je 522 + 5d8: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5db: 89 d3 mov %edx,%ebx + 5dd: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 5e0: 83 ec 04 sub $0x4,%esp + s++; + 5e3: 83 c3 01 add $0x1,%ebx + 5e6: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 5e9: 6a 01 push $0x1 + 5eb: 57 push %edi + 5ec: 56 push %esi + 5ed: e8 e1 fd ff ff call 3d3 + while (*s != 0) { + 5f2: 0f b6 03 movzbl (%ebx),%eax + 5f5: 83 c4 10 add $0x10,%esp + 5f8: 84 c0 test %al,%al + 5fa: 75 e4 jne 5e0 + state = 0; + 5fc: 8b 5d d4 mov -0x2c(%ebp),%ebx + 5ff: 31 c9 xor %ecx,%ecx + 601: e9 1c ff ff ff jmp 522 + 606: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 60d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 610: 83 ec 0c sub $0xc,%esp + 613: b9 0a 00 00 00 mov $0xa,%ecx + 618: 6a 01 push $0x1 + 61a: e9 7b ff ff ff jmp 59a + 61f: 90 nop + putc(fd, *ap); + 620: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 623: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 626: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 628: 6a 01 push $0x1 + 62a: 57 push %edi + 62b: 56 push %esi + putc(fd, *ap); + 62c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 62f: e8 9f fd ff ff call 3d3 + ap++; + 634: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 638: 83 c4 10 add $0x10,%esp + state = 0; + 63b: 31 c9 xor %ecx,%ecx + 63d: e9 e0 fe ff ff jmp 522 + 642: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 648: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 64b: 83 ec 04 sub $0x4,%esp + 64e: e9 2a ff ff ff jmp 57d + 653: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 657: 90 nop + s = "(null)"; + 658: ba 30 08 00 00 mov $0x830,%edx + while (*s != 0) { + 65d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 660: b8 28 00 00 00 mov $0x28,%eax + 665: 89 d3 mov %edx,%ebx + 667: e9 74 ff ff ff jmp 5e0 + 66c: 66 90 xchg %ax,%ax + 66e: 66 90 xchg %ax,%ax + +00000670 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 670: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 671: a1 80 0d 00 00 mov 0xd80,%eax +void free(void *ap) { + 676: 89 e5 mov %esp,%ebp + 678: 57 push %edi + 679: 56 push %esi + 67a: 53 push %ebx + 67b: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 67e: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 681: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 688: 89 c2 mov %eax,%edx + 68a: 8b 00 mov (%eax),%eax + 68c: 39 ca cmp %ecx,%edx + 68e: 73 30 jae 6c0 + 690: 39 c1 cmp %eax,%ecx + 692: 72 04 jb 698 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 694: 39 c2 cmp %eax,%edx + 696: 72 f0 jb 688 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 698: 8b 73 fc mov -0x4(%ebx),%esi + 69b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 69e: 39 f8 cmp %edi,%eax + 6a0: 74 30 je 6d2 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 6a2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 6a5: 8b 42 04 mov 0x4(%edx),%eax + 6a8: 8d 34 c2 lea (%edx,%eax,8),%esi + 6ab: 39 f1 cmp %esi,%ecx + 6ad: 74 3a je 6e9 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 6af: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 6b1: 5b pop %ebx + freep = p; + 6b2: 89 15 80 0d 00 00 mov %edx,0xd80 +} + 6b8: 5e pop %esi + 6b9: 5f pop %edi + 6ba: 5d pop %ebp + 6bb: c3 ret + 6bc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 6c0: 39 c2 cmp %eax,%edx + 6c2: 72 c4 jb 688 + 6c4: 39 c1 cmp %eax,%ecx + 6c6: 73 c0 jae 688 + if (bp + bp->s.size == p->s.ptr) { + 6c8: 8b 73 fc mov -0x4(%ebx),%esi + 6cb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 6ce: 39 f8 cmp %edi,%eax + 6d0: 75 d0 jne 6a2 + bp->s.size += p->s.ptr->s.size; + 6d2: 03 70 04 add 0x4(%eax),%esi + 6d5: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 6d8: 8b 02 mov (%edx),%eax + 6da: 8b 00 mov (%eax),%eax + 6dc: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 6df: 8b 42 04 mov 0x4(%edx),%eax + 6e2: 8d 34 c2 lea (%edx,%eax,8),%esi + 6e5: 39 f1 cmp %esi,%ecx + 6e7: 75 c6 jne 6af + p->s.size += bp->s.size; + 6e9: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 6ec: 89 15 80 0d 00 00 mov %edx,0xd80 + p->s.size += bp->s.size; + 6f2: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 6f5: 8b 4b f8 mov -0x8(%ebx),%ecx + 6f8: 89 0a mov %ecx,(%edx) +} + 6fa: 5b pop %ebx + 6fb: 5e pop %esi + 6fc: 5f pop %edi + 6fd: 5d pop %ebp + 6fe: c3 ret + 6ff: 90 nop + +00000700 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 700: 55 push %ebp + 701: 89 e5 mov %esp,%ebp + 703: 57 push %edi + 704: 56 push %esi + 705: 53 push %ebx + 706: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 709: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 70c: 8b 3d 80 0d 00 00 mov 0xd80,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 712: 8d 70 07 lea 0x7(%eax),%esi + 715: c1 ee 03 shr $0x3,%esi + 718: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 71b: 85 ff test %edi,%edi + 71d: 0f 84 9d 00 00 00 je 7c0 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 723: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 725: 8b 4a 04 mov 0x4(%edx),%ecx + 728: 39 f1 cmp %esi,%ecx + 72a: 73 6a jae 796 + 72c: bb 00 10 00 00 mov $0x1000,%ebx + 731: 39 de cmp %ebx,%esi + 733: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 736: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 73d: 89 45 e4 mov %eax,-0x1c(%ebp) + 740: eb 17 jmp 759 + 742: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 748: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 74a: 8b 48 04 mov 0x4(%eax),%ecx + 74d: 39 f1 cmp %esi,%ecx + 74f: 73 4f jae 7a0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 751: 8b 3d 80 0d 00 00 mov 0xd80,%edi + 757: 89 c2 mov %eax,%edx + 759: 39 d7 cmp %edx,%edi + 75b: 75 eb jne 748 + p = sbrk(nu * sizeof(Header)); + 75d: 83 ec 0c sub $0xc,%esp + 760: ff 75 e4 push -0x1c(%ebp) + 763: e8 4b fc ff ff call 3b3 + if (p == (char*)-1) { + 768: 83 c4 10 add $0x10,%esp + 76b: 83 f8 ff cmp $0xffffffff,%eax + 76e: 74 1c je 78c + hp->s.size = nu; + 770: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 773: 83 ec 0c sub $0xc,%esp + 776: 83 c0 08 add $0x8,%eax + 779: 50 push %eax + 77a: e8 f1 fe ff ff call 670 + return freep; + 77f: 8b 15 80 0d 00 00 mov 0xd80,%edx + if ((p = morecore(nunits)) == 0) { + 785: 83 c4 10 add $0x10,%esp + 788: 85 d2 test %edx,%edx + 78a: 75 bc jne 748 + return 0; + } + } + } +} + 78c: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 78f: 31 c0 xor %eax,%eax +} + 791: 5b pop %ebx + 792: 5e pop %esi + 793: 5f pop %edi + 794: 5d pop %ebp + 795: c3 ret + if (p->s.size >= nunits) { + 796: 89 d0 mov %edx,%eax + 798: 89 fa mov %edi,%edx + 79a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 7a0: 39 ce cmp %ecx,%esi + 7a2: 74 4c je 7f0 + p->s.size -= nunits; + 7a4: 29 f1 sub %esi,%ecx + 7a6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 7a9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 7ac: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 7af: 89 15 80 0d 00 00 mov %edx,0xd80 +} + 7b5: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 7b8: 83 c0 08 add $0x8,%eax +} + 7bb: 5b pop %ebx + 7bc: 5e pop %esi + 7bd: 5f pop %edi + 7be: 5d pop %ebp + 7bf: c3 ret + base.s.ptr = freep = prevp = &base; + 7c0: c7 05 80 0d 00 00 84 movl $0xd84,0xd80 + 7c7: 0d 00 00 + base.s.size = 0; + 7ca: bf 84 0d 00 00 mov $0xd84,%edi + base.s.ptr = freep = prevp = &base; + 7cf: c7 05 84 0d 00 00 84 movl $0xd84,0xd84 + 7d6: 0d 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 7d9: 89 fa mov %edi,%edx + base.s.size = 0; + 7db: c7 05 88 0d 00 00 00 movl $0x0,0xd88 + 7e2: 00 00 00 + if (p->s.size >= nunits) { + 7e5: e9 42 ff ff ff jmp 72c + 7ea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 7f0: 8b 08 mov (%eax),%ecx + 7f2: 89 0a mov %ecx,(%edx) + 7f4: eb b9 jmp 7af diff --git a/cat.c b/cat.c new file mode 100644 index 0000000..b523487 --- /dev/null +++ b/cat.c @@ -0,0 +1,39 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +char buf[512]; + +void cat(int fd) { + int n; + + while ((n = read(fd, buf, sizeof(buf))) > 0) { + if (write(1, buf, n) != n) { + printf(1, "cat: write error\n"); + exit(); + } + } + if (n < 0) { + printf(1, "cat: read error\n"); + exit(); + } +} + +int main(int argc, char *argv[]) { + int fd, i; + + if (argc <= 1) { + cat(0); + exit(); + } + + for (i = 1; i < argc; i++) { + if ((fd = open(argv[i], 0)) < 0) { + printf(1, "cat: cannot open %s\n", argv[i]); + exit(); + } + cat(fd); + close(fd); + } + exit(); +} diff --git a/cat.d b/cat.d new file mode 100644 index 0000000..8f55acc --- /dev/null +++ b/cat.d @@ -0,0 +1 @@ +cat.o: cat.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/cat.o b/cat.o new file mode 100644 index 0000000..58306c2 Binary files /dev/null and b/cat.o differ diff --git a/cat.sym b/cat.sym new file mode 100644 index 0000000..f364576 --- /dev/null +++ b/cat.sym @@ -0,0 +1,50 @@ +00000000 cat.c +00000000 ulib.c +00000000 printf.c +00000420 printint +00000890 digits.0 +00000000 umalloc.c +00000d80 freep +00000d84 base +00000110 strcpy +000004d0 printf +0000040b greeting +00000330 memmove +000003db mknod +00000230 gets +000003ab getpid +00000090 cat +00000700 malloc +000003bb sleep +00000373 pipe +00000403 getch +000003d3 write +00000393 fstat +00000383 kill +0000039b chdir +0000038b exec +0000036b wait +0000037b read +000003e3 unlink +0000035b fork +000003b3 sbrk +000003c3 uptime +00000b74 __bss_start +000001d0 memset +00000000 main +00000140 strcmp +00000413 shutdown +000003a3 dup +00000b80 buf +000002a0 stat +00000b74 _edata +00000d8c _end +000003eb link +00000363 exit +000002f0 atoi +000001a0 strlen +000003cb open +000001f0 strchr +000003f3 mkdir +000003fb close +00000670 free diff --git a/config.xlaunch b/config.xlaunch new file mode 100644 index 0000000..63548ab --- /dev/null +++ b/config.xlaunch @@ -0,0 +1,2 @@ + + diff --git a/console.c b/console.c new file mode 100644 index 0000000..a330c97 --- /dev/null +++ b/console.c @@ -0,0 +1,332 @@ +// Console input and output. +// Input is from the keyboard or serial port. +// Output is written to the screen and serial port. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "traps.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "fs.h" +#include "file.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "x86.h" + +#define INPUT_BUF 128 + +struct kbdbuffer { + char buf[INPUT_BUF]; + uint r; // Read index + uint w; // Write index + uint e; // Edit index +}; + +struct kbdbuffer inputBuffer; + +struct kbdbuffer * input = 0; + +#define C(x) ((x) - '@') // Control-x + + + +static void consputc(int); + +static int panicked = 0; + +static struct { + struct spinlock lock; + int locking; +} cons; + +static void printint(int xx, int base, int sign) { + static char digits[] = "0123456789abcdef"; + char buf[16]; + int i; + uint x; + + if (sign && (sign = xx < 0)) { + x = -xx; + } + else { + x = xx; + } + + i = 0; + do { + buf[i++] = digits[x % base]; + } + while ((x /= base) != 0); + + if (sign) { + buf[i++] = '-'; + } + + while (--i >= 0) { + consputc(buf[i]); + } +} + +// Print to the console. only understands %d, %x, %p, %s. +void cprintf(char *fmt, ...) { + int i, c, locking; + uint *argp; + char *s; + + locking = cons.locking; + if (locking) { + acquire(&cons.lock); + } + + if (fmt == 0) { + panic("null fmt"); + } + + argp = (uint*)(void*)(&fmt + 1); + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { + if (c != '%') { + consputc(c); + continue; + } + c = fmt[++i] & 0xff; + if (c == 0) { + break; + } + switch (c) { + case 'd': + printint(*argp++, 10, 1); + break; + case 'x': + case 'p': + printint(*argp++, 16, 0); + break; + case 's': + if ((s = (char*)*argp++) == 0) { + s = "(null)"; + } + for (; *s; s++) { + consputc(*s); + } + break; + case '%': + consputc('%'); + break; + default: + // Print unknown % sequence to draw attention. + consputc('%'); + consputc(c); + break; + } + } + + if (locking) { + release(&cons.lock); + } +} + +void panic(char *s) { + int i; + uint pcs[10]; + + cli(); + cons.locking = 0; + // use lapiccpunum so that we can call panic from mycpu() + cprintf("lapicid %d: panic: ", lapicid()); + cprintf(s); + cprintf("\n"); + getcallerpcs(&s, pcs); + for (i = 0; i < 10; i++) { + cprintf(" %p", pcs[i]); + } + panicked = 1; // freeze other CPU + for (;;) { + ; + } +} + +#define BACKSPACE 0x100 +#define CRTPORT 0x3d4 +static ushort *crt = (ushort*)P2V(0xb8000); // CGA memory + +static void cgaputc(int c) { + int pos; + + // Cursor position: col + 80*row. + outb(CRTPORT, 14); + pos = inb(CRTPORT + 1) << 8; + outb(CRTPORT, 15); + pos |= inb(CRTPORT + 1); + + if (c == '\n') { + pos += 80 - pos % 80; + } + else if (c == BACKSPACE) { + if (pos > 0) { + --pos; + } + } + else { + crt[pos++] = (c & 0xff) | 0x0700; // black on white + + } + if (pos < 0 || pos > 25 * 80) { + panic("pos under/overflow"); + } + + if ((pos / 80) >= 24) { // Scroll up. + memmove(crt, crt + 80, sizeof(crt[0]) * 23 * 80); + pos -= 80; + memset(crt + pos, 0, sizeof(crt[0]) * (24 * 80 - pos)); + } + + outb(CRTPORT, 14); + outb(CRTPORT + 1, pos >> 8); + outb(CRTPORT, 15); + outb(CRTPORT + 1, pos); + crt[pos] = ' ' | 0x0700; +} + +void consputc(int c) { + if (panicked) { + cli(); + for (;;) { + ; + } + } + + if (c == BACKSPACE) { + uartputc('\b'); + uartputc(' '); + uartputc('\b'); + } + else { + uartputc(c); + } + cgaputc(c); +} + +int consoleget(void) { + int c; + + acquire(&cons.lock); + + while ((c = kbdgetc()) <= 0) { + if (c == 0) { + c = kbdgetc(); + } + } + + release(&cons.lock); + + return c; +} + +void consoleintr(int (*getc)(void)) { + int c, doprocdump = 0; + + acquire(&cons.lock); + while ((c = getc()) >= 0) { + switch (c) { + case C('P'): // Process listing. + // procdump() locks cons.lock indirectly; invoke later + doprocdump = 1; + break; + case C('U'): // Kill line. + while (input->e != input->w && + input->buf[(input->e - 1) % INPUT_BUF] != '\n') { + input->e--; + consputc(BACKSPACE); + } + break; + case C('H'): + case '\x7f': // Backspace + if (input->e != input->w) { + input->e--; + consputc(BACKSPACE); + } + break; + default: + if (c != 0 && input->e - input->r < INPUT_BUF) { + c = (c == '\r') ? '\n' : c; + input->buf[input->e++ % INPUT_BUF] = c; + consputc(c); + if (c == '\n' || c == C('D') || input->e == input->r + INPUT_BUF) { + input->w = input->e; + wakeup(&(input->r)); + } + } + break; + } + } + release(&cons.lock); + if (doprocdump) { + procdump(); // now call procdump() wo. cons.lock held + } +} + +int consoleread(struct inode *ip, char *dst, int n) { + uint target; + int c; + + iunlock(ip); + target = n; + acquire(&cons.lock); + while (n > 0) { + while (input->r == input->w) { + if (myproc()->killed) { + release(&cons.lock); + ilock(ip); + return -1; + } + sleep(&(input->r), &cons.lock); + } + c = input->buf[input->r++ % INPUT_BUF]; + if (c == C('D')) { // EOF + if (n < target) { + // Save ^D for next time, to make sure + // caller gets a 0-byte result. + input->r--; + } + break; + } + *dst++ = c; + --n; + if (c == '\n') { + break; + } + } + release(&cons.lock); + ilock(ip); + + return target - n; +} + +int consolewrite(struct inode *ip, char *buf, int n) { + int i; + + iunlock(ip); + acquire(&cons.lock); + for (i = 0; i < n; i++) { + consputc(buf[i] & 0xff); + } + release(&cons.lock); + ilock(ip); + + return n; +} + +void consoleinit(void) { + initlock(&cons.lock, "console"); + + // Initialise pointer to point to our console input buffer + input = &inputBuffer; + + devsw[CONSOLE].write = consolewrite; + devsw[CONSOLE].read = consoleread; + cons.locking = 1; + + ioapicenable(IRQ_KBD, 0); +} + diff --git a/console.d b/console.d new file mode 100644 index 0000000..7b5564c --- /dev/null +++ b/console.d @@ -0,0 +1,3 @@ +console.o: console.c /usr/include/stdc-predef.h types.h defs.h param.h \ + traps.h spinlock.h sleeplock.h fs.h file.h memlayout.h mmu.h proc.h \ + x86.h diff --git a/console.o b/console.o new file mode 100644 index 0000000..e1c81e9 Binary files /dev/null and b/console.o differ diff --git a/cuth b/cuth new file mode 100644 index 0000000..cce8c0c --- /dev/null +++ b/cuth @@ -0,0 +1,48 @@ +#!/usr/bin/perl + +$| = 1; + +sub writefile($@){ + my ($file, @lines) = @_; + + sleep(1); + open(F, ">$file") || die "open >$file: $!"; + print F @lines; + close(F); +} + +# Cut out #include lines that don't contribute anything. +for($i=0; $i<@ARGV; $i++){ + $file = $ARGV[$i]; + if(!open(F, $file)){ + print STDERR "open $file: $!\n"; + next; + } + @lines = ; + close(F); + + $obj = "$file.o"; + $obj =~ s/\.c\.o$/.o/; + system("touch $file"); + + if(system("make CC='gcc -Werror' $obj >/dev/null 2>\&1") != 0){ + print STDERR "make $obj failed: $rv\n"; + next; + } + + system("cp $file =$file"); + for($j=@lines-1; $j>=0; $j--){ + if($lines[$j] =~ /^#include/){ + $old = $lines[$j]; + $lines[$j] = "/* CUT-H */\n"; + writefile($file, @lines); + if(system("make CC='gcc -Werror' $obj >/dev/null 2>\&1") != 0){ + $lines[$j] = $old; + }else{ + print STDERR "$file $old"; + } + } + } + writefile($file, grep {!/CUT-H/} @lines); + system("rm =$file"); +} diff --git a/date.h b/date.h new file mode 100644 index 0000000..f2e81b0 --- /dev/null +++ b/date.h @@ -0,0 +1,8 @@ +struct rtcdate { + uint second; + uint minute; + uint hour; + uint day; + uint month; + uint year; +}; diff --git a/defs.h b/defs.h new file mode 100644 index 0000000..02710a1 --- /dev/null +++ b/defs.h @@ -0,0 +1,191 @@ +struct buf; +struct context; +struct file; +struct inode; +struct pipe; +struct proc; +struct rtcdate; +struct spinlock; +struct sleeplock; +struct stat; +struct superblock; + +// bio.c +void binit(void); +struct buf* bread(uint, uint); +void brelse(struct buf*); +void bwrite(struct buf*); + +// console.c +void consoleinit(void); +void cprintf(char*, ...); +void consoleintr(int (*)(void)); +int consoleget(void); +void panic(char*) __attribute__((noreturn)); + +// exec.c +int exec(char*, char**); + +// file.c +struct file* filealloc(void); +void fileclose(struct file*); +struct file* filedup(struct file*); +void fileinit(void); +int fileread(struct file*, char*, int n); +int filestat(struct file*, struct stat*); +int filewrite(struct file*, char*, int n); + +// fs.c +void readsb(int dev, struct superblock *sb); +int dirlink(struct inode*, char*, uint); +struct inode* dirlookup(struct inode*, char*, uint*); +struct inode* ialloc(uint, short); +struct inode* idup(struct inode*); +void iinit(int dev); +void ilock(struct inode*); +void iput(struct inode*); +void iunlock(struct inode*); +void iunlockput(struct inode*); +void iupdate(struct inode*); +int namecmp(const char*, const char*); +struct inode* namei(char*); +struct inode* nameiparent(char*, char*); +int readi(struct inode*, char*, uint, uint); +void stati(struct inode*, struct stat*); +int writei(struct inode*, char*, uint, uint); + +// ide.c +void ideinit(void); +void ideintr(void); +void iderw(struct buf*); + +// ioapic.c +void ioapicenable(int irq, int cpu); +extern uchar ioapicid; +void ioapicinit(void); + +// kalloc.c +char* kalloc(void); +void kfree(char*); +void kinit1(void*, void*); +void kinit2(void*, void*); + +// kbd.c +void kbdintr(void); +int kbdgetc(void); + +// lapic.c +void cmostime(struct rtcdate *r); +int lapicid(void); +extern volatile uint* lapic; +void lapiceoi(void); +void lapicinit(void); +void lapicstartap(uchar, uint); +void microdelay(int); + +// log.c +void initlog(int dev); +void log_write(struct buf*); +void begin_op(); +void end_op(); + +// mp.c +extern int ismp; +void mpinit(void); + +// picirq.c +void picenable(int); +void picinit(void); + +// pipe.c +int pipealloc(struct file**, struct file**); +void pipeclose(struct pipe*, int); +int piperead(struct pipe*, char*, int); +int pipewrite(struct pipe*, char*, int); + +// proc.c +int cpuid(void); +void exit(void); +int fork(void); +int growproc(int); +int kill(int); +struct cpu* mycpu(void); +struct proc* myproc(); +void pinit(void); +void procdump(void); +void scheduler(void) __attribute__((noreturn)); +void sched(void); +void setproc(struct proc*); +void sleep(void*, struct spinlock*); +void userinit(void); +int wait(void); +void wakeup(void*); +void yield(void); + +// swtch.S +void swtch(struct context**, struct context*); + +// spinlock.c +void acquire(struct spinlock*); +void getcallerpcs(void*, uint*); +int holding(struct spinlock*); +void initlock(struct spinlock*, char*); +void release(struct spinlock*); +void pushcli(void); +void popcli(void); + +// sleeplock.c +void acquiresleep(struct sleeplock*); +void releasesleep(struct sleeplock*); +int holdingsleep(struct sleeplock*); +void initsleeplock(struct sleeplock*, char*); + +// string.c +int memcmp(const void*, const void*, uint); +void* memmove(void*, const void*, uint); +void* memset(void*, int, uint); +char* safestrcpy(char*, const char*, int); +int strlen(const char*); +int strncmp(const char*, const char*, uint); +char* strncpy(char*, const char*, int); + +// syscall.c +int argint(int, int*); +int argptr(int, char**, int); +int argstr(int, char**); +int fetchint(uint, int*); +int fetchstr(uint, char**); +void syscall(void); + +// timer.c +void timerinit(void); + +// trap.c +void idtinit(void); +extern uint ticks; +void tvinit(void); +extern struct spinlock tickslock; + +// uart.c +void uartinit(void); +void uartintr(void); +void uartputc(int); + +// vm.c +void seginit(void); +void kvmalloc(void); +pde_t* setupkvm(void); +char* uva2ka(pde_t*, char*); +int allocuvm(pde_t*, uint, uint); +int deallocuvm(pde_t*, uint, uint); +void freevm(pde_t*); +void inituvm(pde_t*, char*, uint); +int loaduvm(pde_t*, char*, struct inode*, uint, uint); +pde_t* copyuvm(pde_t*, uint); +void switchuvm(struct proc*); +void switchkvm(void); +int copyout(pde_t*, uint, void*, uint); +void clearpteu(pde_t *pgdir, char *uva); + +// number of elements in fixed-size array +#define NELEM(x) (sizeof(x) / sizeof((x)[0])) diff --git a/echo.asm b/echo.asm new file mode 100644 index 0000000..0997b39 --- /dev/null +++ b/echo.asm @@ -0,0 +1,1169 @@ + +_echo: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: 53 push %ebx + 10: 51 push %ecx + 11: 83 ec 08 sub $0x8,%esp + 14: 8b 31 mov (%ecx),%esi + 16: 8b 79 04 mov 0x4(%ecx),%edi + int i; + + for (i = 1; i < argc; i++) { + 19: 83 fe 01 cmp $0x1,%esi + 1c: 7e 47 jle 65 + 1e: bb 01 00 00 00 mov $0x1,%ebx + printf(1, "%s%s", argv[i], i + 1 < argc ? " " : "\n"); + 23: 83 c3 01 add $0x1,%ebx + 26: 8b 44 9f fc mov -0x4(%edi,%ebx,4),%eax + 2a: 39 f3 cmp %esi,%ebx + 2c: 74 22 je 50 + 2e: 66 90 xchg %ax,%ax + 30: 68 58 07 00 00 push $0x758 + 35: 83 c3 01 add $0x1,%ebx + 38: 50 push %eax + 39: 68 5a 07 00 00 push $0x75a + 3e: 6a 01 push $0x1 + 40: e8 eb 03 00 00 call 430 + 45: 8b 44 9f fc mov -0x4(%edi,%ebx,4),%eax + 49: 83 c4 10 add $0x10,%esp + 4c: 39 f3 cmp %esi,%ebx + 4e: 75 e0 jne 30 + 50: 68 5f 07 00 00 push $0x75f + 55: 50 push %eax + 56: 68 5a 07 00 00 push $0x75a + 5b: 6a 01 push $0x1 + 5d: e8 ce 03 00 00 call 430 + 62: 83 c4 10 add $0x10,%esp + } + exit(); + 65: e8 59 02 00 00 call 2c3 + 6a: 66 90 xchg %ax,%ax + 6c: 66 90 xchg %ax,%ax + 6e: 66 90 xchg %ax,%ax + +00000070 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 70: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 71: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 73: 89 e5 mov %esp,%ebp + 75: 53 push %ebx + 76: 8b 4d 08 mov 0x8(%ebp),%ecx + 79: 8b 5d 0c mov 0xc(%ebp),%ebx + 7c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 80: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 84: 88 14 01 mov %dl,(%ecx,%eax,1) + 87: 83 c0 01 add $0x1,%eax + 8a: 84 d2 test %dl,%dl + 8c: 75 f2 jne 80 + ; + } + return os; +} + 8e: 8b 5d fc mov -0x4(%ebp),%ebx + 91: 89 c8 mov %ecx,%eax + 93: c9 leave + 94: c3 ret + 95: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 9c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000000a0 : + +int strcmp(const char *p, const char *q) { + a0: 55 push %ebp + a1: 89 e5 mov %esp,%ebp + a3: 53 push %ebx + a4: 8b 55 08 mov 0x8(%ebp),%edx + a7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + aa: 0f b6 02 movzbl (%edx),%eax + ad: 84 c0 test %al,%al + af: 75 17 jne c8 + b1: eb 3a jmp ed + b3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + b7: 90 nop + b8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + bc: 83 c2 01 add $0x1,%edx + bf: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + c2: 84 c0 test %al,%al + c4: 74 1a je e0 + p++, q++; + c6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + c8: 0f b6 19 movzbl (%ecx),%ebx + cb: 38 c3 cmp %al,%bl + cd: 74 e9 je b8 + } + return (uchar) * p - (uchar) * q; + cf: 29 d8 sub %ebx,%eax +} + d1: 8b 5d fc mov -0x4(%ebp),%ebx + d4: c9 leave + d5: c3 ret + d6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + dd: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + e0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + e4: 31 c0 xor %eax,%eax + e6: 29 d8 sub %ebx,%eax +} + e8: 8b 5d fc mov -0x4(%ebp),%ebx + eb: c9 leave + ec: c3 ret + return (uchar) * p - (uchar) * q; + ed: 0f b6 19 movzbl (%ecx),%ebx + f0: 31 c0 xor %eax,%eax + f2: eb db jmp cf + f4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + fb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + ff: 90 nop + +00000100 : + +uint strlen(const char *s) { + 100: 55 push %ebp + 101: 89 e5 mov %esp,%ebp + 103: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 106: 80 3a 00 cmpb $0x0,(%edx) + 109: 74 15 je 120 + 10b: 31 c0 xor %eax,%eax + 10d: 8d 76 00 lea 0x0(%esi),%esi + 110: 83 c0 01 add $0x1,%eax + 113: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 117: 89 c1 mov %eax,%ecx + 119: 75 f5 jne 110 + ; + } + return n; +} + 11b: 89 c8 mov %ecx,%eax + 11d: 5d pop %ebp + 11e: c3 ret + 11f: 90 nop + for (n = 0; s[n]; n++) { + 120: 31 c9 xor %ecx,%ecx +} + 122: 5d pop %ebp + 123: 89 c8 mov %ecx,%eax + 125: c3 ret + 126: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 12d: 8d 76 00 lea 0x0(%esi),%esi + +00000130 : + +void* memset(void *dst, int c, uint n) { + 130: 55 push %ebp + 131: 89 e5 mov %esp,%ebp + 133: 57 push %edi + 134: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 137: 8b 4d 10 mov 0x10(%ebp),%ecx + 13a: 8b 45 0c mov 0xc(%ebp),%eax + 13d: 89 d7 mov %edx,%edi + 13f: fc cld + 140: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 142: 8b 7d fc mov -0x4(%ebp),%edi + 145: 89 d0 mov %edx,%eax + 147: c9 leave + 148: c3 ret + 149: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000150 : + +char* strchr(const char *s, char c) { + 150: 55 push %ebp + 151: 89 e5 mov %esp,%ebp + 153: 8b 45 08 mov 0x8(%ebp),%eax + 156: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 15a: 0f b6 10 movzbl (%eax),%edx + 15d: 84 d2 test %dl,%dl + 15f: 75 12 jne 173 + 161: eb 1d jmp 180 + 163: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 167: 90 nop + 168: 0f b6 50 01 movzbl 0x1(%eax),%edx + 16c: 83 c0 01 add $0x1,%eax + 16f: 84 d2 test %dl,%dl + 171: 74 0d je 180 + if (*s == c) { + 173: 38 d1 cmp %dl,%cl + 175: 75 f1 jne 168 + return (char*)s; + } + } + return 0; +} + 177: 5d pop %ebp + 178: c3 ret + 179: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 180: 31 c0 xor %eax,%eax +} + 182: 5d pop %ebp + 183: c3 ret + 184: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 18b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 18f: 90 nop + +00000190 : + +char* gets(char *buf, int max) { + 190: 55 push %ebp + 191: 89 e5 mov %esp,%ebp + 193: 57 push %edi + 194: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 195: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 198: 53 push %ebx + for (i = 0; i + 1 < max;) { + 199: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 19b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 19e: eb 27 jmp 1c7 + cc = read(0, &c, 1); + 1a0: 83 ec 04 sub $0x4,%esp + 1a3: 6a 01 push $0x1 + 1a5: 57 push %edi + 1a6: 6a 00 push $0x0 + 1a8: e8 2e 01 00 00 call 2db + if (cc < 1) { + 1ad: 83 c4 10 add $0x10,%esp + 1b0: 85 c0 test %eax,%eax + 1b2: 7e 1d jle 1d1 + break; + } + buf[i++] = c; + 1b4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 1b8: 8b 55 08 mov 0x8(%ebp),%edx + 1bb: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 1bf: 3c 0a cmp $0xa,%al + 1c1: 74 1d je 1e0 + 1c3: 3c 0d cmp $0xd,%al + 1c5: 74 19 je 1e0 + for (i = 0; i + 1 < max;) { + 1c7: 89 de mov %ebx,%esi + 1c9: 83 c3 01 add $0x1,%ebx + 1cc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1cf: 7c cf jl 1a0 + break; + } + } + buf[i] = '\0'; + 1d1: 8b 45 08 mov 0x8(%ebp),%eax + 1d4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1d8: 8d 65 f4 lea -0xc(%ebp),%esp + 1db: 5b pop %ebx + 1dc: 5e pop %esi + 1dd: 5f pop %edi + 1de: 5d pop %ebp + 1df: c3 ret + buf[i] = '\0'; + 1e0: 8b 45 08 mov 0x8(%ebp),%eax + 1e3: 89 de mov %ebx,%esi + 1e5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 1e9: 8d 65 f4 lea -0xc(%ebp),%esp + 1ec: 5b pop %ebx + 1ed: 5e pop %esi + 1ee: 5f pop %edi + 1ef: 5d pop %ebp + 1f0: c3 ret + 1f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1f8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ff: 90 nop + +00000200 : + +int stat(const char *n, struct stat *st) { + 200: 55 push %ebp + 201: 89 e5 mov %esp,%ebp + 203: 56 push %esi + 204: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 205: 83 ec 08 sub $0x8,%esp + 208: 6a 00 push $0x0 + 20a: ff 75 08 push 0x8(%ebp) + 20d: e8 19 01 00 00 call 32b + if (fd < 0) { + 212: 83 c4 10 add $0x10,%esp + 215: 85 c0 test %eax,%eax + 217: 78 27 js 240 + return -1; + } + r = fstat(fd, st); + 219: 83 ec 08 sub $0x8,%esp + 21c: ff 75 0c push 0xc(%ebp) + 21f: 89 c3 mov %eax,%ebx + 221: 50 push %eax + 222: e8 cc 00 00 00 call 2f3 + close(fd); + 227: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 22a: 89 c6 mov %eax,%esi + close(fd); + 22c: e8 2a 01 00 00 call 35b + return r; + 231: 83 c4 10 add $0x10,%esp +} + 234: 8d 65 f8 lea -0x8(%ebp),%esp + 237: 89 f0 mov %esi,%eax + 239: 5b pop %ebx + 23a: 5e pop %esi + 23b: 5d pop %ebp + 23c: c3 ret + 23d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 240: be ff ff ff ff mov $0xffffffff,%esi + 245: eb ed jmp 234 + 247: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 24e: 66 90 xchg %ax,%ax + +00000250 : + +int atoi(const char *s) { + 250: 55 push %ebp + 251: 89 e5 mov %esp,%ebp + 253: 53 push %ebx + 254: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 257: 0f be 02 movsbl (%edx),%eax + 25a: 8d 48 d0 lea -0x30(%eax),%ecx + 25d: 80 f9 09 cmp $0x9,%cl + n = 0; + 260: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 265: 77 1e ja 285 + 267: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 26e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 270: 83 c2 01 add $0x1,%edx + 273: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 276: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 27a: 0f be 02 movsbl (%edx),%eax + 27d: 8d 58 d0 lea -0x30(%eax),%ebx + 280: 80 fb 09 cmp $0x9,%bl + 283: 76 eb jbe 270 + } + return n; +} + 285: 8b 5d fc mov -0x4(%ebp),%ebx + 288: 89 c8 mov %ecx,%eax + 28a: c9 leave + 28b: c3 ret + 28c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000290 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 290: 55 push %ebp + 291: 89 e5 mov %esp,%ebp + 293: 57 push %edi + 294: 8b 45 10 mov 0x10(%ebp),%eax + 297: 8b 55 08 mov 0x8(%ebp),%edx + 29a: 56 push %esi + 29b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 29e: 85 c0 test %eax,%eax + 2a0: 7e 13 jle 2b5 + 2a2: 01 d0 add %edx,%eax + dst = vdst; + 2a4: 89 d7 mov %edx,%edi + 2a6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2ad: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 2b0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 2b1: 39 f8 cmp %edi,%eax + 2b3: 75 fb jne 2b0 + } + return vdst; +} + 2b5: 5e pop %esi + 2b6: 89 d0 mov %edx,%eax + 2b8: 5f pop %edi + 2b9: 5d pop %ebp + 2ba: c3 ret + +000002bb : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 2bb: b8 01 00 00 00 mov $0x1,%eax + 2c0: cd 40 int $0x40 + 2c2: c3 ret + +000002c3 : +SYSCALL(exit) + 2c3: b8 02 00 00 00 mov $0x2,%eax + 2c8: cd 40 int $0x40 + 2ca: c3 ret + +000002cb : +SYSCALL(wait) + 2cb: b8 03 00 00 00 mov $0x3,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(pipe) + 2d3: b8 04 00 00 00 mov $0x4,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(read) + 2db: b8 05 00 00 00 mov $0x5,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(kill) + 2e3: b8 06 00 00 00 mov $0x6,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(exec) + 2eb: b8 07 00 00 00 mov $0x7,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(fstat) + 2f3: b8 08 00 00 00 mov $0x8,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(chdir) + 2fb: b8 09 00 00 00 mov $0x9,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(dup) + 303: b8 0a 00 00 00 mov $0xa,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(getpid) + 30b: b8 0b 00 00 00 mov $0xb,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(sbrk) + 313: b8 0c 00 00 00 mov $0xc,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(sleep) + 31b: b8 0d 00 00 00 mov $0xd,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(uptime) + 323: b8 0e 00 00 00 mov $0xe,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(open) + 32b: b8 0f 00 00 00 mov $0xf,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(write) + 333: b8 10 00 00 00 mov $0x10,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(mknod) + 33b: b8 11 00 00 00 mov $0x11,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(unlink) + 343: b8 12 00 00 00 mov $0x12,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(link) + 34b: b8 13 00 00 00 mov $0x13,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(mkdir) + 353: b8 14 00 00 00 mov $0x14,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(close) + 35b: b8 15 00 00 00 mov $0x15,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(getch) + 363: b8 16 00 00 00 mov $0x16,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + +0000036b : +SYSCALL(greeting) + 36b: b8 17 00 00 00 mov $0x17,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(shutdown) + 373: b8 18 00 00 00 mov $0x18,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + 37b: 66 90 xchg %ax,%ax + 37d: 66 90 xchg %ax,%ax + 37f: 90 nop + +00000380 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 380: 55 push %ebp + 381: 89 e5 mov %esp,%ebp + 383: 57 push %edi + 384: 56 push %esi + 385: 53 push %ebx + 386: 83 ec 3c sub $0x3c,%esp + 389: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 38c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 38e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 391: 85 d2 test %edx,%edx + 393: 0f 89 7f 00 00 00 jns 418 + 399: f6 45 08 01 testb $0x1,0x8(%ebp) + 39d: 74 79 je 418 + neg = 1; + 39f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 3a6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 3a8: 31 db xor %ebx,%ebx + 3aa: 8d 75 d7 lea -0x29(%ebp),%esi + 3ad: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 3b0: 89 c8 mov %ecx,%eax + 3b2: 31 d2 xor %edx,%edx + 3b4: 89 cf mov %ecx,%edi + 3b6: f7 75 c4 divl -0x3c(%ebp) + 3b9: 0f b6 92 c0 07 00 00 movzbl 0x7c0(%edx),%edx + 3c0: 89 45 c0 mov %eax,-0x40(%ebp) + 3c3: 89 d8 mov %ebx,%eax + 3c5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3c8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3cb: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3ce: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3d1: 76 dd jbe 3b0 + if (neg) { + 3d3: 8b 4d bc mov -0x44(%ebp),%ecx + 3d6: 85 c9 test %ecx,%ecx + 3d8: 74 0c je 3e6 + buf[i++] = '-'; + 3da: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3df: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 3e1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 3e6: 8b 7d b8 mov -0x48(%ebp),%edi + 3e9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 3ed: eb 07 jmp 3f6 + 3ef: 90 nop + putc(fd, buf[i]); + 3f0: 0f b6 13 movzbl (%ebx),%edx + 3f3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 3f6: 83 ec 04 sub $0x4,%esp + 3f9: 88 55 d7 mov %dl,-0x29(%ebp) + 3fc: 6a 01 push $0x1 + 3fe: 56 push %esi + 3ff: 57 push %edi + 400: e8 2e ff ff ff call 333 + while (--i >= 0) { + 405: 83 c4 10 add $0x10,%esp + 408: 39 de cmp %ebx,%esi + 40a: 75 e4 jne 3f0 + } +} + 40c: 8d 65 f4 lea -0xc(%ebp),%esp + 40f: 5b pop %ebx + 410: 5e pop %esi + 411: 5f pop %edi + 412: 5d pop %ebp + 413: c3 ret + 414: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 418: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 41f: eb 87 jmp 3a8 + 421: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 428: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 42f: 90 nop + +00000430 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 430: 55 push %ebp + 431: 89 e5 mov %esp,%ebp + 433: 57 push %edi + 434: 56 push %esi + 435: 53 push %ebx + 436: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 439: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 43c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 43f: 0f b6 13 movzbl (%ebx),%edx + 442: 84 d2 test %dl,%dl + 444: 74 6a je 4b0 + ap = (uint*)(void*)&fmt + 1; + 446: 8d 45 10 lea 0x10(%ebp),%eax + 449: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 44c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 44f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 451: 89 45 d0 mov %eax,-0x30(%ebp) + 454: eb 36 jmp 48c + 456: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 45d: 8d 76 00 lea 0x0(%esi),%esi + 460: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 463: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 468: 83 f8 25 cmp $0x25,%eax + 46b: 74 15 je 482 + write(fd, &c, 1); + 46d: 83 ec 04 sub $0x4,%esp + 470: 88 55 e7 mov %dl,-0x19(%ebp) + 473: 6a 01 push $0x1 + 475: 57 push %edi + 476: 56 push %esi + 477: e8 b7 fe ff ff call 333 + 47c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 47f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 482: 0f b6 13 movzbl (%ebx),%edx + 485: 83 c3 01 add $0x1,%ebx + 488: 84 d2 test %dl,%dl + 48a: 74 24 je 4b0 + c = fmt[i] & 0xff; + 48c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 48f: 85 c9 test %ecx,%ecx + 491: 74 cd je 460 + } + } + else if (state == '%') { + 493: 83 f9 25 cmp $0x25,%ecx + 496: 75 ea jne 482 + if (c == 'd') { + 498: 83 f8 25 cmp $0x25,%eax + 49b: 0f 84 07 01 00 00 je 5a8 + 4a1: 83 e8 63 sub $0x63,%eax + 4a4: 83 f8 15 cmp $0x15,%eax + 4a7: 77 17 ja 4c0 + 4a9: ff 24 85 68 07 00 00 jmp *0x768(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 4b0: 8d 65 f4 lea -0xc(%ebp),%esp + 4b3: 5b pop %ebx + 4b4: 5e pop %esi + 4b5: 5f pop %edi + 4b6: 5d pop %ebp + 4b7: c3 ret + 4b8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4bf: 90 nop + write(fd, &c, 1); + 4c0: 83 ec 04 sub $0x4,%esp + 4c3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4c6: 6a 01 push $0x1 + 4c8: 57 push %edi + 4c9: 56 push %esi + 4ca: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4ce: e8 60 fe ff ff call 333 + putc(fd, c); + 4d3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4d7: 83 c4 0c add $0xc,%esp + 4da: 88 55 e7 mov %dl,-0x19(%ebp) + 4dd: 6a 01 push $0x1 + 4df: 57 push %edi + 4e0: 56 push %esi + 4e1: e8 4d fe ff ff call 333 + putc(fd, c); + 4e6: 83 c4 10 add $0x10,%esp + state = 0; + 4e9: 31 c9 xor %ecx,%ecx + 4eb: eb 95 jmp 482 + 4ed: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 4f0: 83 ec 0c sub $0xc,%esp + 4f3: b9 10 00 00 00 mov $0x10,%ecx + 4f8: 6a 00 push $0x0 + 4fa: 8b 45 d0 mov -0x30(%ebp),%eax + 4fd: 8b 10 mov (%eax),%edx + 4ff: 89 f0 mov %esi,%eax + 501: e8 7a fe ff ff call 380 + ap++; + 506: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 50a: 83 c4 10 add $0x10,%esp + state = 0; + 50d: 31 c9 xor %ecx,%ecx + 50f: e9 6e ff ff ff jmp 482 + 514: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 518: 8b 45 d0 mov -0x30(%ebp),%eax + 51b: 8b 10 mov (%eax),%edx + ap++; + 51d: 83 c0 04 add $0x4,%eax + 520: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 523: 85 d2 test %edx,%edx + 525: 0f 84 8d 00 00 00 je 5b8 + while (*s != 0) { + 52b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 52e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 530: 84 c0 test %al,%al + 532: 0f 84 4a ff ff ff je 482 + 538: 89 5d d4 mov %ebx,-0x2c(%ebp) + 53b: 89 d3 mov %edx,%ebx + 53d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 540: 83 ec 04 sub $0x4,%esp + s++; + 543: 83 c3 01 add $0x1,%ebx + 546: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 549: 6a 01 push $0x1 + 54b: 57 push %edi + 54c: 56 push %esi + 54d: e8 e1 fd ff ff call 333 + while (*s != 0) { + 552: 0f b6 03 movzbl (%ebx),%eax + 555: 83 c4 10 add $0x10,%esp + 558: 84 c0 test %al,%al + 55a: 75 e4 jne 540 + state = 0; + 55c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 55f: 31 c9 xor %ecx,%ecx + 561: e9 1c ff ff ff jmp 482 + 566: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 56d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 570: 83 ec 0c sub $0xc,%esp + 573: b9 0a 00 00 00 mov $0xa,%ecx + 578: 6a 01 push $0x1 + 57a: e9 7b ff ff ff jmp 4fa + 57f: 90 nop + putc(fd, *ap); + 580: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 583: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 586: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 588: 6a 01 push $0x1 + 58a: 57 push %edi + 58b: 56 push %esi + putc(fd, *ap); + 58c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 58f: e8 9f fd ff ff call 333 + ap++; + 594: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 598: 83 c4 10 add $0x10,%esp + state = 0; + 59b: 31 c9 xor %ecx,%ecx + 59d: e9 e0 fe ff ff jmp 482 + 5a2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 5a8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 5ab: 83 ec 04 sub $0x4,%esp + 5ae: e9 2a ff ff ff jmp 4dd + 5b3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 5b7: 90 nop + s = "(null)"; + 5b8: ba 61 07 00 00 mov $0x761,%edx + while (*s != 0) { + 5bd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5c0: b8 28 00 00 00 mov $0x28,%eax + 5c5: 89 d3 mov %edx,%ebx + 5c7: e9 74 ff ff ff jmp 540 + 5cc: 66 90 xchg %ax,%ax + 5ce: 66 90 xchg %ax,%ax + +000005d0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5d0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5d1: a1 74 0a 00 00 mov 0xa74,%eax +void free(void *ap) { + 5d6: 89 e5 mov %esp,%ebp + 5d8: 57 push %edi + 5d9: 56 push %esi + 5da: 53 push %ebx + 5db: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5de: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5e1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5e8: 89 c2 mov %eax,%edx + 5ea: 8b 00 mov (%eax),%eax + 5ec: 39 ca cmp %ecx,%edx + 5ee: 73 30 jae 620 + 5f0: 39 c1 cmp %eax,%ecx + 5f2: 72 04 jb 5f8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 5f4: 39 c2 cmp %eax,%edx + 5f6: 72 f0 jb 5e8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 5f8: 8b 73 fc mov -0x4(%ebx),%esi + 5fb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 5fe: 39 f8 cmp %edi,%eax + 600: 74 30 je 632 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 602: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 605: 8b 42 04 mov 0x4(%edx),%eax + 608: 8d 34 c2 lea (%edx,%eax,8),%esi + 60b: 39 f1 cmp %esi,%ecx + 60d: 74 3a je 649 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 60f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 611: 5b pop %ebx + freep = p; + 612: 89 15 74 0a 00 00 mov %edx,0xa74 +} + 618: 5e pop %esi + 619: 5f pop %edi + 61a: 5d pop %ebp + 61b: c3 ret + 61c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 620: 39 c2 cmp %eax,%edx + 622: 72 c4 jb 5e8 + 624: 39 c1 cmp %eax,%ecx + 626: 73 c0 jae 5e8 + if (bp + bp->s.size == p->s.ptr) { + 628: 8b 73 fc mov -0x4(%ebx),%esi + 62b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 62e: 39 f8 cmp %edi,%eax + 630: 75 d0 jne 602 + bp->s.size += p->s.ptr->s.size; + 632: 03 70 04 add 0x4(%eax),%esi + 635: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 638: 8b 02 mov (%edx),%eax + 63a: 8b 00 mov (%eax),%eax + 63c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 63f: 8b 42 04 mov 0x4(%edx),%eax + 642: 8d 34 c2 lea (%edx,%eax,8),%esi + 645: 39 f1 cmp %esi,%ecx + 647: 75 c6 jne 60f + p->s.size += bp->s.size; + 649: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 64c: 89 15 74 0a 00 00 mov %edx,0xa74 + p->s.size += bp->s.size; + 652: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 655: 8b 4b f8 mov -0x8(%ebx),%ecx + 658: 89 0a mov %ecx,(%edx) +} + 65a: 5b pop %ebx + 65b: 5e pop %esi + 65c: 5f pop %edi + 65d: 5d pop %ebp + 65e: c3 ret + 65f: 90 nop + +00000660 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 660: 55 push %ebp + 661: 89 e5 mov %esp,%ebp + 663: 57 push %edi + 664: 56 push %esi + 665: 53 push %ebx + 666: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 669: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 66c: 8b 3d 74 0a 00 00 mov 0xa74,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 672: 8d 70 07 lea 0x7(%eax),%esi + 675: c1 ee 03 shr $0x3,%esi + 678: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 67b: 85 ff test %edi,%edi + 67d: 0f 84 9d 00 00 00 je 720 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 683: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 685: 8b 4a 04 mov 0x4(%edx),%ecx + 688: 39 f1 cmp %esi,%ecx + 68a: 73 6a jae 6f6 + 68c: bb 00 10 00 00 mov $0x1000,%ebx + 691: 39 de cmp %ebx,%esi + 693: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 696: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 69d: 89 45 e4 mov %eax,-0x1c(%ebp) + 6a0: eb 17 jmp 6b9 + 6a2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6a8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 6aa: 8b 48 04 mov 0x4(%eax),%ecx + 6ad: 39 f1 cmp %esi,%ecx + 6af: 73 4f jae 700 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 6b1: 8b 3d 74 0a 00 00 mov 0xa74,%edi + 6b7: 89 c2 mov %eax,%edx + 6b9: 39 d7 cmp %edx,%edi + 6bb: 75 eb jne 6a8 + p = sbrk(nu * sizeof(Header)); + 6bd: 83 ec 0c sub $0xc,%esp + 6c0: ff 75 e4 push -0x1c(%ebp) + 6c3: e8 4b fc ff ff call 313 + if (p == (char*)-1) { + 6c8: 83 c4 10 add $0x10,%esp + 6cb: 83 f8 ff cmp $0xffffffff,%eax + 6ce: 74 1c je 6ec + hp->s.size = nu; + 6d0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6d3: 83 ec 0c sub $0xc,%esp + 6d6: 83 c0 08 add $0x8,%eax + 6d9: 50 push %eax + 6da: e8 f1 fe ff ff call 5d0 + return freep; + 6df: 8b 15 74 0a 00 00 mov 0xa74,%edx + if ((p = morecore(nunits)) == 0) { + 6e5: 83 c4 10 add $0x10,%esp + 6e8: 85 d2 test %edx,%edx + 6ea: 75 bc jne 6a8 + return 0; + } + } + } +} + 6ec: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 6ef: 31 c0 xor %eax,%eax +} + 6f1: 5b pop %ebx + 6f2: 5e pop %esi + 6f3: 5f pop %edi + 6f4: 5d pop %ebp + 6f5: c3 ret + if (p->s.size >= nunits) { + 6f6: 89 d0 mov %edx,%eax + 6f8: 89 fa mov %edi,%edx + 6fa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 700: 39 ce cmp %ecx,%esi + 702: 74 4c je 750 + p->s.size -= nunits; + 704: 29 f1 sub %esi,%ecx + 706: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 709: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 70c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 70f: 89 15 74 0a 00 00 mov %edx,0xa74 +} + 715: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 718: 83 c0 08 add $0x8,%eax +} + 71b: 5b pop %ebx + 71c: 5e pop %esi + 71d: 5f pop %edi + 71e: 5d pop %ebp + 71f: c3 ret + base.s.ptr = freep = prevp = &base; + 720: c7 05 74 0a 00 00 78 movl $0xa78,0xa74 + 727: 0a 00 00 + base.s.size = 0; + 72a: bf 78 0a 00 00 mov $0xa78,%edi + base.s.ptr = freep = prevp = &base; + 72f: c7 05 78 0a 00 00 78 movl $0xa78,0xa78 + 736: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 739: 89 fa mov %edi,%edx + base.s.size = 0; + 73b: c7 05 7c 0a 00 00 00 movl $0x0,0xa7c + 742: 00 00 00 + if (p->s.size >= nunits) { + 745: e9 42 ff ff ff jmp 68c + 74a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 750: 8b 08 mov (%eax),%ecx + 752: 89 0a mov %ecx,(%edx) + 754: eb b9 jmp 70f diff --git a/echo.c b/echo.c new file mode 100644 index 0000000..89b105c --- /dev/null +++ b/echo.c @@ -0,0 +1,12 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + int i; + + for (i = 1; i < argc; i++) { + printf(1, "%s%s", argv[i], i + 1 < argc ? " " : "\n"); + } + exit(); +} diff --git a/echo.d b/echo.d new file mode 100644 index 0000000..16a6098 --- /dev/null +++ b/echo.d @@ -0,0 +1 @@ +echo.o: echo.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/echo.o b/echo.o new file mode 100644 index 0000000..1ebc79c Binary files /dev/null and b/echo.o differ diff --git a/echo.sym b/echo.sym new file mode 100644 index 0000000..f2e8205 --- /dev/null +++ b/echo.sym @@ -0,0 +1,48 @@ +00000000 echo.c +00000000 ulib.c +00000000 printf.c +00000380 printint +000007c0 digits.0 +00000000 umalloc.c +00000a74 freep +00000a78 base +00000070 strcpy +00000430 printf +0000036b greeting +00000290 memmove +0000033b mknod +00000190 gets +0000030b getpid +00000660 malloc +0000031b sleep +000002d3 pipe +00000363 getch +00000333 write +000002f3 fstat +000002e3 kill +000002fb chdir +000002eb exec +000002cb wait +000002db read +00000343 unlink +000002bb fork +00000313 sbrk +00000323 uptime +00000a74 __bss_start +00000130 memset +00000000 main +000000a0 strcmp +00000373 shutdown +00000303 dup +00000200 stat +00000a74 _edata +00000a80 _end +0000034b link +000002c3 exit +00000250 atoi +00000100 strlen +0000032b open +00000150 strchr +00000353 mkdir +0000035b close +000005d0 free diff --git a/elf.h b/elf.h new file mode 100644 index 0000000..0a312a5 --- /dev/null +++ b/elf.h @@ -0,0 +1,42 @@ +// Format of an ELF executable file + +#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian + +// File header +struct elfhdr { + uint magic; // must equal ELF_MAGIC + uchar elf[12]; + ushort type; + ushort machine; + uint version; + uint entry; + uint phoff; + uint shoff; + uint flags; + ushort ehsize; + ushort phentsize; + ushort phnum; + ushort shentsize; + ushort shnum; + ushort shstrndx; +}; + +// Program section header +struct proghdr { + uint type; + uint off; + uint vaddr; + uint paddr; + uint filesz; + uint memsz; + uint flags; + uint align; +}; + +// Values for Proghdr type +#define ELF_PROG_LOAD 1 + +// Flag bits for Proghdr flags +#define ELF_PROG_FLAG_EXEC 1 +#define ELF_PROG_FLAG_WRITE 2 +#define ELF_PROG_FLAG_READ 4 diff --git a/entry.S b/entry.S new file mode 100644 index 0000000..2d9504d --- /dev/null +++ b/entry.S @@ -0,0 +1,68 @@ +# The xv6 kernel starts executing in this file. This file is linked with +# the kernel C code, so it can refer to kernel symbols such as main(). +# The boot block (bootasm.S and bootmain.c) jumps to entry below. + +# Multiboot header, for multiboot boot loaders like GNU Grub. +# http://www.gnu.org/software/grub/manual/multiboot/multiboot.html +# +# Using GRUB 2, you can boot xv6 from a file stored in a +# Linux file system by copying kernel or kernelmemfs to /boot +# and then adding this menu entry: +# +# menuentry "xv6" { +# insmod ext2 +# set root='(hd0,msdos1)' +# set kernel='/boot/kernel' +# echo "Loading ${kernel}..." +# multiboot ${kernel} ${kernel} +# boot +# } + +#include "asm.h" +#include "memlayout.h" +#include "mmu.h" +#include "param.h" + +# Multiboot header. Data to direct multiboot loader. +.p2align 2 +.text +.globl multiboot_header +multiboot_header: + #define magic 0x1badb002 + #define flags 0 + .long magic + .long flags + .long (-magic-flags) + +# By convention, the _start symbol specifies the ELF entry point. +# Since we haven't set up virtual memory yet, our entry point is +# the physical address of 'entry'. +.globl _start +_start = V2P_WO(entry) + +# Entering xv6 on boot processor, with paging off. +.globl entry +entry: + # Turn on page size extension for 4Mbyte pages + movl %cr4, %eax + orl $(CR4_PSE), %eax + movl %eax, %cr4 + # Set page directory + movl $(V2P_WO(entrypgdir)), %eax + movl %eax, %cr3 + # Turn on paging. + movl %cr0, %eax + orl $(CR0_PG|CR0_WP), %eax + movl %eax, %cr0 + + # Set up the stack pointer. + movl $(stack + KSTACKSIZE), %esp + + # Jump to main(), and switch to executing at + # high addresses. The indirect call is needed because + # the assembler produces a PC-relative instruction + # for a direct jump. + mov $main, %eax + jmp *%eax + +.comm stack, KSTACKSIZE diff --git a/entry.o b/entry.o new file mode 100644 index 0000000..a61fc4a Binary files /dev/null and b/entry.o differ diff --git a/entryother b/entryother new file mode 100644 index 0000000..0e1f31a Binary files /dev/null and b/entryother differ diff --git a/entryother.S b/entryother.S new file mode 100644 index 0000000..93aea8e --- /dev/null +++ b/entryother.S @@ -0,0 +1,89 @@ +#include "asm.h" +#include "memlayout.h" +#include "mmu.h" + +# Each non-boot CPU ("AP") is started up in response to a STARTUP +# IPI from the boot CPU. Section B.4.2 of the Multi-Processor +# Specification says that the AP will start in real mode with CS:IP +# set to XY00:0000, where XY is an 8-bit value sent with the +# STARTUP. Thus this code must start at a 4096-byte boundary. +# +# Because this code sets DS to zero, it must sit +# at an address in the low 2^16 bytes. +# +# Startothers (in main.c) sends the STARTUPs one at a time. +# It copies this code (start) at 0x7000. It puts the address of +# a newly allocated per-core stack in start-4,the address of the +# place to jump to (mpenter) in start-8, and the physical address +# of entrypgdir in start-12. +# +# This code combines elements of bootasm.S and entry.S. + +.code16 +.globl start +start: + cli + + # Zero data segment registers DS, ES, and SS. + xorw %ax,%ax + movw %ax,%ds + movw %ax,%es + movw %ax,%ss + + # Switch from real to protected mode. Use a bootstrap GDT that makes + # virtual addresses map directly to physical addresses so that the + # effective memory map doesn't change during the transition. + lgdt gdtdesc + movl %cr0, %eax + orl $CR0_PE, %eax + movl %eax, %cr0 + + # Complete the transition to 32-bit protected mode by using a long jmp + # to reload %cs and %eip. The segment descriptors are set up with no + # translation, so that the mapping is still the identity mapping. + ljmpl $(SEG_KCODE<<3), $(start32) + + +.code32 # Tell assembler to generate 32-bit code now. +start32: + # Set up the protected-mode data segment registers + movw $(SEG_KDATA<<3), %ax # Our data segment selector + movw %ax, %ds # -> DS: Data Segment + movw %ax, %es # -> ES: Extra Segment + movw %ax, %ss # -> SS: Stack Segment + movw $0, %ax # Zero segments not ready for use + movw %ax, %fs # -> FS + movw %ax, %gs # -> GS + + # Turn on page size extension for 4Mbyte pages + movl %cr4, %eax + orl $(CR4_PSE), %eax + movl %eax, %cr4 + # Use entrypgdir as our initial page table + movl (start-12), %eax + movl %eax, %cr3 + # Turn on paging. + movl %cr0, %eax + orl $(CR0_PE|CR0_PG|CR0_WP), %eax + movl %eax, %cr0 + + # Switch to the stack allocated by startothers() + movl (start-4), %esp + # Call mpenter() + call *(start-8) + + # We should never return. +spin: + jmp spin + +.p2align 2 +gdt: + SEG_NULLASM + SEG_ASM(STA_X|STA_R, 0, 0xffffffff) + SEG_ASM(STA_W, 0, 0xffffffff) + + +gdtdesc: + .word (gdtdesc - gdt - 1) + .long gdt + diff --git a/entryother.asm b/entryother.asm new file mode 100644 index 0000000..656001f --- /dev/null +++ b/entryother.asm @@ -0,0 +1,115 @@ + +bootblockother.o: file format elf32-i386 + + +Disassembly of section .text: + +00007000 : +# This code combines elements of bootasm.S and entry.S. + +.code16 +.globl start +start: + cli + 7000: fa cli + + # Zero data segment registers DS, ES, and SS. + xorw %ax,%ax + 7001: 31 c0 xor %eax,%eax + movw %ax,%ds + 7003: 8e d8 mov %eax,%ds + movw %ax,%es + 7005: 8e c0 mov %eax,%es + movw %ax,%ss + 7007: 8e d0 mov %eax,%ss + + # Switch from real to protected mode. Use a bootstrap GDT that makes + # virtual addresses map directly to physical addresses so that the + # effective memory map doesn't change during the transition. + lgdt gdtdesc + 7009: 0f 01 16 lgdtl (%esi) + 700c: 74 70 je 707e <_end+0x2> + movl %cr0, %eax + 700e: 0f 20 c0 mov %cr0,%eax + orl $CR0_PE, %eax + 7011: 66 83 c8 01 or $0x1,%ax + movl %eax, %cr0 + 7015: 0f 22 c0 mov %eax,%cr0 + + # Complete the transition to 32-bit protected mode by using a long jmp + # to reload %cs and %eip. The segment descriptors are set up with no + # translation, so that the mapping is still the identity mapping. + ljmpl $(SEG_KCODE<<3), $(start32) + 7018: 66 ea 20 70 00 00 ljmpw $0x0,$0x7020 + 701e: 08 00 or %al,(%eax) + +00007020 : + + +.code32 # Tell assembler to generate 32-bit code now. +start32: + # Set up the protected-mode data segment registers + movw $(SEG_KDATA<<3), %ax # Our data segment selector + 7020: 66 b8 10 00 mov $0x10,%ax + movw %ax, %ds # -> DS: Data Segment + 7024: 8e d8 mov %eax,%ds + movw %ax, %es # -> ES: Extra Segment + 7026: 8e c0 mov %eax,%es + movw %ax, %ss # -> SS: Stack Segment + 7028: 8e d0 mov %eax,%ss + movw $0, %ax # Zero segments not ready for use + 702a: 66 b8 00 00 mov $0x0,%ax + movw %ax, %fs # -> FS + 702e: 8e e0 mov %eax,%fs + movw %ax, %gs # -> GS + 7030: 8e e8 mov %eax,%gs + + # Turn on page size extension for 4Mbyte pages + movl %cr4, %eax + 7032: 0f 20 e0 mov %cr4,%eax + orl $(CR4_PSE), %eax + 7035: 83 c8 10 or $0x10,%eax + movl %eax, %cr4 + 7038: 0f 22 e0 mov %eax,%cr4 + # Use entrypgdir as our initial page table + movl (start-12), %eax + 703b: a1 f4 6f 00 00 mov 0x6ff4,%eax + movl %eax, %cr3 + 7040: 0f 22 d8 mov %eax,%cr3 + # Turn on paging. + movl %cr0, %eax + 7043: 0f 20 c0 mov %cr0,%eax + orl $(CR0_PE|CR0_PG|CR0_WP), %eax + 7046: 0d 01 00 01 80 or $0x80010001,%eax + movl %eax, %cr0 + 704b: 0f 22 c0 mov %eax,%cr0 + + # Switch to the stack allocated by startothers() + movl (start-4), %esp + 704e: 8b 25 fc 6f 00 00 mov 0x6ffc,%esp + # Call mpenter() + call *(start-8) + 7054: ff 15 f8 6f 00 00 call *0x6ff8 + +0000705a : + + # We should never return. +spin: + jmp spin + 705a: eb fe jmp 705a + +0000705c : + ... + 7064: ff (bad) + 7065: ff 00 incl (%eax) + 7067: 00 00 add %al,(%eax) + 7069: 9a cf 00 ff ff 00 00 lcall $0x0,$0xffff00cf + 7070: 00 .byte 0x0 + 7071: 92 xchg %eax,%edx + 7072: cf iret + ... + +00007074 : + 7074: 17 pop %ss + 7075: 00 5c 70 00 add %bl,0x0(%eax,%esi,2) + ... diff --git a/entryother.d b/entryother.d new file mode 100644 index 0000000..a140303 --- /dev/null +++ b/entryother.d @@ -0,0 +1 @@ +entryother.o: entryother.S asm.h memlayout.h mmu.h diff --git a/entryother.o b/entryother.o new file mode 100644 index 0000000..ffdaa2e Binary files /dev/null and b/entryother.o differ diff --git a/exec.c b/exec.c new file mode 100644 index 0000000..73c54b1 --- /dev/null +++ b/exec.c @@ -0,0 +1,142 @@ +#include "types.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "defs.h" +#include "x86.h" +#include "elf.h" + +void cleanupexec(pde_t * pgdir, struct inode *ip) { + if (pgdir) { + freevm(pgdir); + } + if (ip) { + iunlockput(ip); + end_op(); + } +} + +int exec(char *path, char **argv) { + char *s, *last; + int i, off; + uint argc, sz, sp, ustack[3 + MAXARG + 1]; + struct elfhdr elf; + struct inode *ip; + struct proghdr ph; + pde_t *pgdir, *oldpgdir; + struct proc *curproc = myproc(); + + begin_op(); + + if ((ip = namei(path)) == 0) { + end_op(); + cprintf("exec: fail\n"); + return -1; + } + ilock(ip); + pgdir = 0; + + // Check ELF header + if (readi(ip, (char*)&elf, 0, sizeof(elf)) != sizeof(elf)) { + cleanupexec(pgdir, ip); + return -1; + } + if (elf.magic != ELF_MAGIC) { + cleanupexec(pgdir, ip); + return -1; + } + + if ((pgdir = setupkvm()) == 0) { + cleanupexec(pgdir, ip); + return -1; + } + + // Load program into memory. + sz = 0; + for (i = 0, off = elf.phoff; i < elf.phnum; i++, off += sizeof(ph)) { + if (readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) { + cleanupexec(pgdir, ip); + return -1; + } + if (ph.type != ELF_PROG_LOAD) { + continue; + } + if (ph.memsz < ph.filesz) { + cleanupexec(pgdir, ip); + return -1; + } + if (ph.vaddr + ph.memsz < ph.vaddr) { + cleanupexec(pgdir, ip); + return -1; + } + if ((sz = allocuvm(pgdir, sz, ph.vaddr + ph.memsz)) == 0) { + cleanupexec(pgdir, ip); + return -1; + } + if (ph.vaddr % PGSIZE != 0) { + cleanupexec(pgdir, ip); + return -1; + } + if (loaduvm(pgdir, (char*)ph.vaddr, ip, ph.off, ph.filesz) < 0) { + cleanupexec(pgdir, ip); + return -1; + } + } + iunlockput(ip); + end_op(); + ip = 0; + + // Allocate two pages at the next page boundary. + // Make the first inaccessible. Use the second as the user stack. + sz = PGROUNDUP(sz); + if ((sz = allocuvm(pgdir, sz, sz + 2 * PGSIZE)) == 0) { + cleanupexec(pgdir, ip); + return -1; + } + clearpteu(pgdir, (char*)(sz - 2 * PGSIZE)); + sp = sz; + + // Push argument strings, prepare rest of stack in ustack. + for (argc = 0; argv[argc]; argc++) { + if (argc >= MAXARG) { + cleanupexec(pgdir, ip); + return -1; + } + sp = (sp - (strlen(argv[argc]) + 1)) & ~3; + if (copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0) { + cleanupexec(pgdir, ip); + return -1; + } + ustack[3 + argc] = sp; + } + ustack[3 + argc] = 0; + + ustack[0] = 0xffffffff; // fake return PC + ustack[1] = argc; + ustack[2] = sp - (argc + 1) * 4; // argv pointer + + sp -= (3 + argc + 1) * 4; + if (copyout(pgdir, sp, ustack, (3 + argc + 1) * 4) < 0) { + cleanupexec(pgdir, ip); + return -1; + } + + // Save program name for debugging. + for (last = s = path; *s; s++) { + if (*s == '/') { + last = s + 1; + } + } + safestrcpy(curproc->name, last, sizeof(curproc->name)); + + // Commit to the user image. + oldpgdir = curproc->pgdir; + curproc->pgdir = pgdir; + curproc->sz = sz; + curproc->tf->eip = elf.entry; // main + curproc->tf->esp = sp; + switchuvm(curproc); + freevm(oldpgdir); + return 0; +} diff --git a/exec.d b/exec.d new file mode 100644 index 0000000..0400275 --- /dev/null +++ b/exec.d @@ -0,0 +1,2 @@ +exec.o: exec.c /usr/include/stdc-predef.h types.h param.h memlayout.h \ + mmu.h proc.h defs.h x86.h elf.h diff --git a/exec.o b/exec.o new file mode 100644 index 0000000..796192d Binary files /dev/null and b/exec.o differ diff --git a/fcntl.h b/fcntl.h new file mode 100644 index 0000000..d565483 --- /dev/null +++ b/fcntl.h @@ -0,0 +1,4 @@ +#define O_RDONLY 0x000 +#define O_WRONLY 0x001 +#define O_RDWR 0x002 +#define O_CREATE 0x200 diff --git a/file.c b/file.c new file mode 100644 index 0000000..bbd83ab --- /dev/null +++ b/file.c @@ -0,0 +1,155 @@ +// +// File descriptors +// + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "fs.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "file.h" + +struct devsw devsw[NDEV]; +struct { + struct spinlock lock; + struct file file[NFILE]; +} ftable; + +void fileinit(void) { + initlock(&ftable.lock, "ftable"); +} + +// Allocate a file structure. +struct file* filealloc(void) { + struct file *f; + + acquire(&ftable.lock); + for (f = ftable.file; f < ftable.file + NFILE; f++) { + if (f->ref == 0) { + f->ref = 1; + release(&ftable.lock); + return f; + } + } + release(&ftable.lock); + return 0; +} + +// Increment ref count for file f. +struct file* filedup(struct file *f) { + acquire(&ftable.lock); + if (f->ref < 1) { + panic("filedup"); + } + f->ref++; + release(&ftable.lock); + return f; +} + +// Close file f. (Decrement ref count, close when reaches 0.) +void fileclose(struct file *f) { + struct file ff; + + acquire(&ftable.lock); + if (f->ref < 1) { + panic("fileclose"); + } + if (--f->ref > 0) { + release(&ftable.lock); + return; + } + ff = *f; + f->ref = 0; + f->type = FD_NONE; + release(&ftable.lock); + + if (ff.type == FD_PIPE) { + pipeclose(ff.pipe, ff.writable); + } + else if (ff.type == FD_INODE) { + begin_op(); + iput(ff.ip); + end_op(); + } +} + +// Get metadata about file f. +int filestat(struct file *f, struct stat *st) { + if (f->type == FD_INODE) { + ilock(f->ip); + stati(f->ip, st); + iunlock(f->ip); + return 0; + } + return -1; +} + +// Read from file f. +int fileread(struct file *f, char *addr, int n) { + int r; + + if (f->readable == 0) { + return -1; + } + if (f->type == FD_PIPE) { + return piperead(f->pipe, addr, n); + } + if (f->type == FD_INODE) { + ilock(f->ip); + if ((r = readi(f->ip, addr, f->off, n)) > 0) { + f->off += r; + } + iunlock(f->ip); + return r; + } + panic("fileread"); +} + + +// Write to file f. +int filewrite(struct file *f, char *addr, int n) { + int r; + + if (f->writable == 0) { + return -1; + } + if (f->type == FD_PIPE) { + return pipewrite(f->pipe, addr, n); + } + if (f->type == FD_INODE) { + // write a few blocks at a time to avoid exceeding + // the maximum log transaction size, including + // i-node, indirect block, allocation blocks, + // and 2 blocks of slop for non-aligned writes. + // this really belongs lower down, since writei() + // might be writing a device like the console. + int max = ((MAXOPBLOCKS - 1 - 1 - 2) / 2) * 512; + int i = 0; + while (i < n) { + int n1 = n - i; + if (n1 > max) { + n1 = max; + } + + begin_op(); + ilock(f->ip); + if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) { + f->off += r; + } + iunlock(f->ip); + end_op(); + + if (r < 0) { + break; + } + if (r != n1) { + panic("short filewrite"); + } + i += r; + } + return i == n ? n : -1; + } + panic("filewrite"); +} + diff --git a/file.d b/file.d new file mode 100644 index 0000000..fea73d1 --- /dev/null +++ b/file.d @@ -0,0 +1,2 @@ +file.o: file.c /usr/include/stdc-predef.h types.h defs.h param.h fs.h \ + spinlock.h sleeplock.h file.h diff --git a/file.h b/file.h new file mode 100644 index 0000000..7ffe18b --- /dev/null +++ b/file.h @@ -0,0 +1,37 @@ +struct file { + enum { FD_NONE, FD_PIPE, FD_INODE } type; + int ref; // reference count + char readable; + char writable; + struct pipe *pipe; + struct inode *ip; + uint off; +}; + + +// in-memory copy of an inode +struct inode { + uint dev; // Device number + uint inum; // Inode number + int ref; // Reference count + struct sleeplock lock; // protects everything below here + int valid; // inode has been read from disk? + + short type; // copy of disk inode + short major; + short minor; + short nlink; + uint size; + uint addrs[NDIRECT + 1]; +}; + +// table mapping major device number to +// device functions +struct devsw { + int (*read)(struct inode*, char*, int); + int (*write)(struct inode*, char*, int); +}; + +extern struct devsw devsw[]; + +#define CONSOLE 1 diff --git a/file.o b/file.o new file mode 100644 index 0000000..89a3fe4 Binary files /dev/null and b/file.o differ diff --git a/forktest.asm b/forktest.asm new file mode 100644 index 0000000..fbbdbfe --- /dev/null +++ b/forktest.asm @@ -0,0 +1,673 @@ + +_forktest: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: + } + + printf(1, "fork test OK\n"); +} + +int main(void) { + 0: 55 push %ebp + 1: 89 e5 mov %esp,%ebp + 3: 83 e4 f0 and $0xfffffff0,%esp + forktest(); + 6: e8 35 00 00 00 call 40 + exit(); + b: e8 63 03 00 00 call 373 + +00000010 : +void printf(int fd, const char *s, ...) { + 10: 55 push %ebp + 11: 89 e5 mov %esp,%ebp + 13: 53 push %ebx + 14: 83 ec 10 sub $0x10,%esp + 17: 8b 5d 0c mov 0xc(%ebp),%ebx + write(fd, s, strlen(s)); + 1a: 53 push %ebx + 1b: e8 90 01 00 00 call 1b0 + 20: 83 c4 0c add $0xc,%esp + 23: 50 push %eax + 24: 53 push %ebx + 25: ff 75 08 push 0x8(%ebp) + 28: e8 b6 03 00 00 call 3e3 +} + 2d: 8b 5d fc mov -0x4(%ebp),%ebx + 30: 83 c4 10 add $0x10,%esp + 33: c9 leave + 34: c3 ret + 35: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000040 : +void forktest(void) { + 40: 55 push %ebp + 41: 89 e5 mov %esp,%ebp + 43: 53 push %ebx + for (n = 0; n < N; n++) { + 44: 31 db xor %ebx,%ebx +void forktest(void) { + 46: 83 ec 10 sub $0x10,%esp + write(fd, s, strlen(s)); + 49: 68 2c 04 00 00 push $0x42c + 4e: e8 5d 01 00 00 call 1b0 + 53: 83 c4 0c add $0xc,%esp + 56: 50 push %eax + 57: 68 2c 04 00 00 push $0x42c + 5c: 6a 01 push $0x1 + 5e: e8 80 03 00 00 call 3e3 + 63: 83 c4 10 add $0x10,%esp + 66: eb 19 jmp 81 + 68: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 6f: 90 nop + if (pid == 0) { + 70: 74 58 je ca + for (n = 0; n < N; n++) { + 72: 83 c3 01 add $0x1,%ebx + 75: 81 fb e8 03 00 00 cmp $0x3e8,%ebx + 7b: 0f 84 83 00 00 00 je 104 + pid = fork(); + 81: e8 e5 02 00 00 call 36b + if (pid < 0) { + 86: 85 c0 test %eax,%eax + 88: 79 e6 jns 70 + for (; n > 0; n--) { + 8a: 85 db test %ebx,%ebx + 8c: 74 10 je 9e + 8e: 66 90 xchg %ax,%ax + if (wait() < 0) { + 90: e8 e6 02 00 00 call 37b + 95: 85 c0 test %eax,%eax + 97: 78 36 js cf + for (; n > 0; n--) { + 99: 83 eb 01 sub $0x1,%ebx + 9c: 75 f2 jne 90 + if (wait() != -1) { + 9e: e8 d8 02 00 00 call 37b + a3: 83 f8 ff cmp $0xffffffff,%eax + a6: 75 49 jne f1 + write(fd, s, strlen(s)); + a8: 83 ec 0c sub $0xc,%esp + ab: 68 5e 04 00 00 push $0x45e + b0: e8 fb 00 00 00 call 1b0 + b5: 83 c4 0c add $0xc,%esp + b8: 50 push %eax + b9: 68 5e 04 00 00 push $0x45e + be: 6a 01 push $0x1 + c0: e8 1e 03 00 00 call 3e3 +} + c5: 8b 5d fc mov -0x4(%ebp),%ebx + c8: c9 leave + c9: c3 ret + exit(); + ca: e8 a4 02 00 00 call 373 + write(fd, s, strlen(s)); + cf: 83 ec 0c sub $0xc,%esp + d2: 68 37 04 00 00 push $0x437 + d7: e8 d4 00 00 00 call 1b0 + dc: 83 c4 0c add $0xc,%esp + df: 50 push %eax + e0: 68 37 04 00 00 push $0x437 + e5: 6a 01 push $0x1 + e7: e8 f7 02 00 00 call 3e3 + exit(); + ec: e8 82 02 00 00 call 373 + printf(1, "wait got too many\n"); + f1: 52 push %edx + f2: 52 push %edx + f3: 68 4b 04 00 00 push $0x44b + f8: 6a 01 push $0x1 + fa: e8 11 ff ff ff call 10 + exit(); + ff: e8 6f 02 00 00 call 373 + printf(1, "fork claimed to work N times!\n", N); + 104: 50 push %eax + 105: 68 e8 03 00 00 push $0x3e8 + 10a: 68 6c 04 00 00 push $0x46c + 10f: 6a 01 push $0x1 + 111: e8 fa fe ff ff call 10 + exit(); + 116: e8 58 02 00 00 call 373 + 11b: 66 90 xchg %ax,%ax + 11d: 66 90 xchg %ax,%ax + 11f: 90 nop + +00000120 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 120: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 121: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 123: 89 e5 mov %esp,%ebp + 125: 53 push %ebx + 126: 8b 4d 08 mov 0x8(%ebp),%ecx + 129: 8b 5d 0c mov 0xc(%ebp),%ebx + 12c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 130: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 134: 88 14 01 mov %dl,(%ecx,%eax,1) + 137: 83 c0 01 add $0x1,%eax + 13a: 84 d2 test %dl,%dl + 13c: 75 f2 jne 130 + ; + } + return os; +} + 13e: 8b 5d fc mov -0x4(%ebp),%ebx + 141: 89 c8 mov %ecx,%eax + 143: c9 leave + 144: c3 ret + 145: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 14c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000150 : + +int strcmp(const char *p, const char *q) { + 150: 55 push %ebp + 151: 89 e5 mov %esp,%ebp + 153: 53 push %ebx + 154: 8b 55 08 mov 0x8(%ebp),%edx + 157: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 15a: 0f b6 02 movzbl (%edx),%eax + 15d: 84 c0 test %al,%al + 15f: 75 17 jne 178 + 161: eb 3a jmp 19d + 163: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 167: 90 nop + 168: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 16c: 83 c2 01 add $0x1,%edx + 16f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 172: 84 c0 test %al,%al + 174: 74 1a je 190 + p++, q++; + 176: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 178: 0f b6 19 movzbl (%ecx),%ebx + 17b: 38 c3 cmp %al,%bl + 17d: 74 e9 je 168 + } + return (uchar) * p - (uchar) * q; + 17f: 29 d8 sub %ebx,%eax +} + 181: 8b 5d fc mov -0x4(%ebp),%ebx + 184: c9 leave + 185: c3 ret + 186: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 18d: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 190: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 194: 31 c0 xor %eax,%eax + 196: 29 d8 sub %ebx,%eax +} + 198: 8b 5d fc mov -0x4(%ebp),%ebx + 19b: c9 leave + 19c: c3 ret + return (uchar) * p - (uchar) * q; + 19d: 0f b6 19 movzbl (%ecx),%ebx + 1a0: 31 c0 xor %eax,%eax + 1a2: eb db jmp 17f + 1a4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1af: 90 nop + +000001b0 : + +uint strlen(const char *s) { + 1b0: 55 push %ebp + 1b1: 89 e5 mov %esp,%ebp + 1b3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 1b6: 80 3a 00 cmpb $0x0,(%edx) + 1b9: 74 15 je 1d0 + 1bb: 31 c0 xor %eax,%eax + 1bd: 8d 76 00 lea 0x0(%esi),%esi + 1c0: 83 c0 01 add $0x1,%eax + 1c3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 1c7: 89 c1 mov %eax,%ecx + 1c9: 75 f5 jne 1c0 + ; + } + return n; +} + 1cb: 89 c8 mov %ecx,%eax + 1cd: 5d pop %ebp + 1ce: c3 ret + 1cf: 90 nop + for (n = 0; s[n]; n++) { + 1d0: 31 c9 xor %ecx,%ecx +} + 1d2: 5d pop %ebp + 1d3: 89 c8 mov %ecx,%eax + 1d5: c3 ret + 1d6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1dd: 8d 76 00 lea 0x0(%esi),%esi + +000001e0 : + +void* memset(void *dst, int c, uint n) { + 1e0: 55 push %ebp + 1e1: 89 e5 mov %esp,%ebp + 1e3: 57 push %edi + 1e4: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 1e7: 8b 4d 10 mov 0x10(%ebp),%ecx + 1ea: 8b 45 0c mov 0xc(%ebp),%eax + 1ed: 89 d7 mov %edx,%edi + 1ef: fc cld + 1f0: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 1f2: 8b 7d fc mov -0x4(%ebp),%edi + 1f5: 89 d0 mov %edx,%eax + 1f7: c9 leave + 1f8: c3 ret + 1f9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000200 : + +char* strchr(const char *s, char c) { + 200: 55 push %ebp + 201: 89 e5 mov %esp,%ebp + 203: 8b 45 08 mov 0x8(%ebp),%eax + 206: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 20a: 0f b6 10 movzbl (%eax),%edx + 20d: 84 d2 test %dl,%dl + 20f: 75 12 jne 223 + 211: eb 1d jmp 230 + 213: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 217: 90 nop + 218: 0f b6 50 01 movzbl 0x1(%eax),%edx + 21c: 83 c0 01 add $0x1,%eax + 21f: 84 d2 test %dl,%dl + 221: 74 0d je 230 + if (*s == c) { + 223: 38 d1 cmp %dl,%cl + 225: 75 f1 jne 218 + return (char*)s; + } + } + return 0; +} + 227: 5d pop %ebp + 228: c3 ret + 229: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 230: 31 c0 xor %eax,%eax +} + 232: 5d pop %ebp + 233: c3 ret + 234: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 23b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 23f: 90 nop + +00000240 : + +char* gets(char *buf, int max) { + 240: 55 push %ebp + 241: 89 e5 mov %esp,%ebp + 243: 57 push %edi + 244: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 245: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 248: 53 push %ebx + for (i = 0; i + 1 < max;) { + 249: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 24b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 24e: eb 27 jmp 277 + cc = read(0, &c, 1); + 250: 83 ec 04 sub $0x4,%esp + 253: 6a 01 push $0x1 + 255: 57 push %edi + 256: 6a 00 push $0x0 + 258: e8 2e 01 00 00 call 38b + if (cc < 1) { + 25d: 83 c4 10 add $0x10,%esp + 260: 85 c0 test %eax,%eax + 262: 7e 1d jle 281 + break; + } + buf[i++] = c; + 264: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 268: 8b 55 08 mov 0x8(%ebp),%edx + 26b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 26f: 3c 0a cmp $0xa,%al + 271: 74 1d je 290 + 273: 3c 0d cmp $0xd,%al + 275: 74 19 je 290 + for (i = 0; i + 1 < max;) { + 277: 89 de mov %ebx,%esi + 279: 83 c3 01 add $0x1,%ebx + 27c: 3b 5d 0c cmp 0xc(%ebp),%ebx + 27f: 7c cf jl 250 + break; + } + } + buf[i] = '\0'; + 281: 8b 45 08 mov 0x8(%ebp),%eax + 284: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 288: 8d 65 f4 lea -0xc(%ebp),%esp + 28b: 5b pop %ebx + 28c: 5e pop %esi + 28d: 5f pop %edi + 28e: 5d pop %ebp + 28f: c3 ret + buf[i] = '\0'; + 290: 8b 45 08 mov 0x8(%ebp),%eax + 293: 89 de mov %ebx,%esi + 295: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 299: 8d 65 f4 lea -0xc(%ebp),%esp + 29c: 5b pop %ebx + 29d: 5e pop %esi + 29e: 5f pop %edi + 29f: 5d pop %ebp + 2a0: c3 ret + 2a1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2a8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2af: 90 nop + +000002b0 : + +int stat(const char *n, struct stat *st) { + 2b0: 55 push %ebp + 2b1: 89 e5 mov %esp,%ebp + 2b3: 56 push %esi + 2b4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 2b5: 83 ec 08 sub $0x8,%esp + 2b8: 6a 00 push $0x0 + 2ba: ff 75 08 push 0x8(%ebp) + 2bd: e8 19 01 00 00 call 3db + if (fd < 0) { + 2c2: 83 c4 10 add $0x10,%esp + 2c5: 85 c0 test %eax,%eax + 2c7: 78 27 js 2f0 + return -1; + } + r = fstat(fd, st); + 2c9: 83 ec 08 sub $0x8,%esp + 2cc: ff 75 0c push 0xc(%ebp) + 2cf: 89 c3 mov %eax,%ebx + 2d1: 50 push %eax + 2d2: e8 cc 00 00 00 call 3a3 + close(fd); + 2d7: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 2da: 89 c6 mov %eax,%esi + close(fd); + 2dc: e8 2a 01 00 00 call 40b + return r; + 2e1: 83 c4 10 add $0x10,%esp +} + 2e4: 8d 65 f8 lea -0x8(%ebp),%esp + 2e7: 89 f0 mov %esi,%eax + 2e9: 5b pop %ebx + 2ea: 5e pop %esi + 2eb: 5d pop %ebp + 2ec: c3 ret + 2ed: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 2f0: be ff ff ff ff mov $0xffffffff,%esi + 2f5: eb ed jmp 2e4 + 2f7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2fe: 66 90 xchg %ax,%ax + +00000300 : + +int atoi(const char *s) { + 300: 55 push %ebp + 301: 89 e5 mov %esp,%ebp + 303: 53 push %ebx + 304: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 307: 0f be 02 movsbl (%edx),%eax + 30a: 8d 48 d0 lea -0x30(%eax),%ecx + 30d: 80 f9 09 cmp $0x9,%cl + n = 0; + 310: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 315: 77 1e ja 335 + 317: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 31e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 320: 83 c2 01 add $0x1,%edx + 323: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 326: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 32a: 0f be 02 movsbl (%edx),%eax + 32d: 8d 58 d0 lea -0x30(%eax),%ebx + 330: 80 fb 09 cmp $0x9,%bl + 333: 76 eb jbe 320 + } + return n; +} + 335: 8b 5d fc mov -0x4(%ebp),%ebx + 338: 89 c8 mov %ecx,%eax + 33a: c9 leave + 33b: c3 ret + 33c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000340 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 340: 55 push %ebp + 341: 89 e5 mov %esp,%ebp + 343: 57 push %edi + 344: 8b 45 10 mov 0x10(%ebp),%eax + 347: 8b 55 08 mov 0x8(%ebp),%edx + 34a: 56 push %esi + 34b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 34e: 85 c0 test %eax,%eax + 350: 7e 13 jle 365 + 352: 01 d0 add %edx,%eax + dst = vdst; + 354: 89 d7 mov %edx,%edi + 356: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 35d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 360: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 361: 39 f8 cmp %edi,%eax + 363: 75 fb jne 360 + } + return vdst; +} + 365: 5e pop %esi + 366: 89 d0 mov %edx,%eax + 368: 5f pop %edi + 369: 5d pop %ebp + 36a: c3 ret + +0000036b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 36b: b8 01 00 00 00 mov $0x1,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(exit) + 373: b8 02 00 00 00 mov $0x2,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + +0000037b : +SYSCALL(wait) + 37b: b8 03 00 00 00 mov $0x3,%eax + 380: cd 40 int $0x40 + 382: c3 ret + +00000383 : +SYSCALL(pipe) + 383: b8 04 00 00 00 mov $0x4,%eax + 388: cd 40 int $0x40 + 38a: c3 ret + +0000038b : +SYSCALL(read) + 38b: b8 05 00 00 00 mov $0x5,%eax + 390: cd 40 int $0x40 + 392: c3 ret + +00000393 : +SYSCALL(kill) + 393: b8 06 00 00 00 mov $0x6,%eax + 398: cd 40 int $0x40 + 39a: c3 ret + +0000039b : +SYSCALL(exec) + 39b: b8 07 00 00 00 mov $0x7,%eax + 3a0: cd 40 int $0x40 + 3a2: c3 ret + +000003a3 : +SYSCALL(fstat) + 3a3: b8 08 00 00 00 mov $0x8,%eax + 3a8: cd 40 int $0x40 + 3aa: c3 ret + +000003ab : +SYSCALL(chdir) + 3ab: b8 09 00 00 00 mov $0x9,%eax + 3b0: cd 40 int $0x40 + 3b2: c3 ret + +000003b3 : +SYSCALL(dup) + 3b3: b8 0a 00 00 00 mov $0xa,%eax + 3b8: cd 40 int $0x40 + 3ba: c3 ret + +000003bb : +SYSCALL(getpid) + 3bb: b8 0b 00 00 00 mov $0xb,%eax + 3c0: cd 40 int $0x40 + 3c2: c3 ret + +000003c3 : +SYSCALL(sbrk) + 3c3: b8 0c 00 00 00 mov $0xc,%eax + 3c8: cd 40 int $0x40 + 3ca: c3 ret + +000003cb : +SYSCALL(sleep) + 3cb: b8 0d 00 00 00 mov $0xd,%eax + 3d0: cd 40 int $0x40 + 3d2: c3 ret + +000003d3 : +SYSCALL(uptime) + 3d3: b8 0e 00 00 00 mov $0xe,%eax + 3d8: cd 40 int $0x40 + 3da: c3 ret + +000003db : +SYSCALL(open) + 3db: b8 0f 00 00 00 mov $0xf,%eax + 3e0: cd 40 int $0x40 + 3e2: c3 ret + +000003e3 : +SYSCALL(write) + 3e3: b8 10 00 00 00 mov $0x10,%eax + 3e8: cd 40 int $0x40 + 3ea: c3 ret + +000003eb : +SYSCALL(mknod) + 3eb: b8 11 00 00 00 mov $0x11,%eax + 3f0: cd 40 int $0x40 + 3f2: c3 ret + +000003f3 : +SYSCALL(unlink) + 3f3: b8 12 00 00 00 mov $0x12,%eax + 3f8: cd 40 int $0x40 + 3fa: c3 ret + +000003fb : +SYSCALL(link) + 3fb: b8 13 00 00 00 mov $0x13,%eax + 400: cd 40 int $0x40 + 402: c3 ret + +00000403 : +SYSCALL(mkdir) + 403: b8 14 00 00 00 mov $0x14,%eax + 408: cd 40 int $0x40 + 40a: c3 ret + +0000040b : +SYSCALL(close) + 40b: b8 15 00 00 00 mov $0x15,%eax + 410: cd 40 int $0x40 + 412: c3 ret + +00000413 : +SYSCALL(getch) + 413: b8 16 00 00 00 mov $0x16,%eax + 418: cd 40 int $0x40 + 41a: c3 ret + +0000041b : +SYSCALL(greeting) + 41b: b8 17 00 00 00 mov $0x17,%eax + 420: cd 40 int $0x40 + 422: c3 ret + +00000423 : +SYSCALL(shutdown) + 423: b8 18 00 00 00 mov $0x18,%eax + 428: cd 40 int $0x40 + 42a: c3 ret diff --git a/forktest.c b/forktest.c new file mode 100644 index 0000000..e997cc1 --- /dev/null +++ b/forktest.c @@ -0,0 +1,52 @@ +// Test that fork fails gracefully. +// Tiny executable so that the limit can be filling the proc table. + +#include "types.h" +#include "stat.h" +#include "user.h" + +#define N 1000 + +void printf(int fd, const char *s, ...) { + write(fd, s, strlen(s)); +} + +void forktest(void) { + int n, pid; + + printf(1, "fork test\n"); + + for (n = 0; n < N; n++) { + pid = fork(); + if (pid < 0) { + break; + } + if (pid == 0) { + exit(); + } + } + + if (n == N) { + printf(1, "fork claimed to work N times!\n", N); + exit(); + } + + for (; n > 0; n--) { + if (wait() < 0) { + printf(1, "wait stopped early\n"); + exit(); + } + } + + if (wait() != -1) { + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); +} + +int main(void) { + forktest(); + exit(); +} diff --git a/forktest.d b/forktest.d new file mode 100644 index 0000000..d31a0c2 --- /dev/null +++ b/forktest.d @@ -0,0 +1 @@ +forktest.o: forktest.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/forktest.o b/forktest.o new file mode 100644 index 0000000..5ec77c5 Binary files /dev/null and b/forktest.o differ diff --git a/fs.c b/fs.c new file mode 100644 index 0000000..9ada0f2 --- /dev/null +++ b/fs.c @@ -0,0 +1,649 @@ +// File system implementation. Five layers: +// + Blocks: allocator for raw disk blocks. +// + Log: crash recovery for multi-step updates. +// + Files: inode allocator, reading, writing, metadata. +// + Directories: inode with special contents (list of other inodes!) +// + Names: paths like /usr/rtm/xv6/fs.c for convenient naming. +// +// This file contains the low-level file system manipulation +// routines. The (higher-level) system call implementations +// are in sysfile.c. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "stat.h" +#include "mmu.h" +#include "proc.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "fs.h" +#include "buf.h" +#include "file.h" + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +static void itrunc(struct inode*); +// there should be one superblock per disk device, but we run with +// only one device +struct superblock sb; + +// Read the super block. +void readsb(int dev, struct superblock *sb) { + struct buf *bp; + + bp = bread(dev, 1); + memmove(sb, bp->data, sizeof(*sb)); + brelse(bp); +} + +// Zero a block. +static void bzero(int dev, int bno) { + struct buf *bp; + + bp = bread(dev, bno); + memset(bp->data, 0, BSIZE); + log_write(bp); + brelse(bp); +} + +// Blocks. + +// Allocate a zeroed disk block. +static uint balloc(uint dev) { + int b, bi, m; + struct buf *bp; + + bp = 0; + for (b = 0; b < sb.size; b += BPB) { + bp = bread(dev, BBLOCK(b, sb)); + for (bi = 0; bi < BPB && b + bi < sb.size; bi++) { + m = 1 << (bi % 8); + if ((bp->data[bi / 8] & m) == 0) { // Is block free? + bp->data[bi / 8] |= m; // Mark block in use. + log_write(bp); + brelse(bp); + bzero(dev, b + bi); + return b + bi; + } + } + brelse(bp); + } + panic("balloc: out of blocks"); +} + +// Free a disk block. +static void bfree(int dev, uint b) { + struct buf *bp; + int bi, m; + + bp = bread(dev, BBLOCK(b, sb)); + bi = b % BPB; + m = 1 << (bi % 8); + if ((bp->data[bi / 8] & m) == 0) { + panic("freeing free block"); + } + bp->data[bi / 8] &= ~m; + log_write(bp); + brelse(bp); +} + +// Inodes. +// +// An inode describes a single unnamed file. +// The inode disk structure holds metadata: the file's type, +// its size, the number of links referring to it, and the +// list of blocks holding the file's content. +// +// The inodes are laid out sequentially on disk at +// sb.startinode. Each inode has a number, indicating its +// position on the disk. +// +// The kernel keeps a cache of in-use inodes in memory +// to provide a place for synchronizing access +// to inodes used by multiple processes. The cached +// inodes include book-keeping information that is +// not stored on disk: ip->ref and ip->valid. +// +// An inode and its in-memory representation go through a +// sequence of states before they can be used by the +// rest of the file system code. +// +// * Allocation: an inode is allocated if its type (on disk) +// is non-zero. ialloc() allocates, and iput() frees if +// the reference and link counts have fallen to zero. +// +// * Referencing in cache: an entry in the inode cache +// is free if ip->ref is zero. Otherwise ip->ref tracks +// the number of in-memory pointers to the entry (open +// files and current directories). iget() finds or +// creates a cache entry and increments its ref; iput() +// decrements ref. +// +// * Valid: the information (type, size, &c) in an inode +// cache entry is only correct when ip->valid is 1. +// ilock() reads the inode from +// the disk and sets ip->valid, while iput() clears +// ip->valid if ip->ref has fallen to zero. +// +// * Locked: file system code may only examine and modify +// the information in an inode and its content if it +// has first locked the inode. +// +// Thus a typical sequence is: +// ip = iget(dev, inum) +// ilock(ip) +// ... examine and modify ip->xxx ... +// iunlock(ip) +// iput(ip) +// +// ilock() is separate from iget() so that system calls can +// get a long-term reference to an inode (as for an open file) +// and only lock it for short periods (e.g., in read()). +// The separation also helps avoid deadlock and races during +// pathname lookup. iget() increments ip->ref so that the inode +// stays cached and pointers to it remain valid. +// +// Many internal file system functions expect the caller to +// have locked the inodes involved; this lets callers create +// multi-step atomic operations. +// +// The icache.lock spin-lock protects the allocation of icache +// entries. Since ip->ref indicates whether an entry is free, +// and ip->dev and ip->inum indicate which i-node an entry +// holds, one must hold icache.lock while using any of those fields. +// +// An ip->lock sleep-lock protects all ip-> fields other than ref, +// dev, and inum. One must hold ip->lock in order to +// read or write that inode's ip->valid, ip->size, ip->type, &c. + +struct { + struct spinlock lock; + struct inode inode[NINODE]; +} icache; + +void iinit(int dev) { + int i = 0; + + initlock(&icache.lock, "icache"); + for (i = 0; i < NINODE; i++) { + initsleeplock(&icache.inode[i].lock, "inode"); + } + + readsb(dev, &sb); + cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\ + inodestart %d bmap start %d\n", sb.size, sb.nblocks, + sb.ninodes, sb.nlog, sb.logstart, sb.inodestart, + sb.bmapstart); +} + +static struct inode* iget(uint dev, uint inum); + + +// Allocate an inode on device dev. +// Mark it as allocated by giving it type type. +// Returns an unlocked but allocated and referenced inode. +struct inode* ialloc(uint dev, short type) { + int inum; + struct buf *bp; + struct dinode *dip; + + for (inum = 1; inum < sb.ninodes; inum++) { + bp = bread(dev, IBLOCK(inum, sb)); + dip = (struct dinode*)bp->data + inum % IPB; + if (dip->type == 0) { // a free inode + memset(dip, 0, sizeof(*dip)); + dip->type = type; + log_write(bp); // mark it allocated on the disk + brelse(bp); + return iget(dev, inum); + } + brelse(bp); + } + panic("ialloc: no inodes"); +} + +// Copy a modified in-memory inode to disk. +// Must be called after every change to an ip->xxx field +// that lives on disk, since i-node cache is write-through. +// Caller must hold ip->lock. +void iupdate(struct inode *ip) { + struct buf *bp; + struct dinode *dip; + + bp = bread(ip->dev, IBLOCK(ip->inum, sb)); + dip = (struct dinode*)bp->data + ip->inum % IPB; + dip->type = ip->type; + dip->major = ip->major; + dip->minor = ip->minor; + dip->nlink = ip->nlink; + dip->size = ip->size; + memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); + log_write(bp); + brelse(bp); +} + +// Find the inode with number inum on device dev +// and return the in-memory copy. Does not lock +// the inode and does not read it from disk. +static struct inode* iget(uint dev, uint inum) { + struct inode *ip, *empty; + + acquire(&icache.lock); + + // Is the inode already cached? + empty = 0; + for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { + if (ip->ref > 0 && ip->dev == dev && ip->inum == inum) { + ip->ref++; + release(&icache.lock); + return ip; + } + if (empty == 0 && ip->ref == 0) { // Remember empty slot. + empty = ip; + } + } + + // Recycle an inode cache entry. + if (empty == 0) { + panic("iget: no inodes"); + } + + ip = empty; + ip->dev = dev; + ip->inum = inum; + ip->ref = 1; + ip->valid = 0; + release(&icache.lock); + + return ip; +} + +// Increment reference count for ip. +// Returns ip to enable ip = idup(ip1) idiom. +struct inode* idup(struct inode *ip) { + acquire(&icache.lock); + ip->ref++; + release(&icache.lock); + return ip; +} + +// Lock the given inode. +// Reads the inode from disk if necessary. +void ilock(struct inode *ip) { + struct buf *bp; + struct dinode *dip; + + if (ip == 0 || ip->ref < 1) { + panic("ilock"); + } + + acquiresleep(&ip->lock); + + if (ip->valid == 0) { + bp = bread(ip->dev, IBLOCK(ip->inum, sb)); + dip = (struct dinode*)bp->data + ip->inum % IPB; + ip->type = dip->type; + ip->major = dip->major; + ip->minor = dip->minor; + ip->nlink = dip->nlink; + ip->size = dip->size; + memmove(ip->addrs, dip->addrs, sizeof(ip->addrs)); + brelse(bp); + ip->valid = 1; + if (ip->type == 0) { + panic("ilock: no type"); + } + } +} + +// Unlock the given inode. +void iunlock(struct inode *ip) { + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { + panic("iunlock"); + } + + releasesleep(&ip->lock); +} + +// Drop a reference to an in-memory inode. +// If that was the last reference, the inode cache entry can +// be recycled. +// If that was the last reference and the inode has no links +// to it, free the inode (and its content) on disk. +// All calls to iput() must be inside a transaction in +// case it has to free the inode. +void iput(struct inode *ip) { + acquiresleep(&ip->lock); + if (ip->valid && ip->nlink == 0) { + acquire(&icache.lock); + int r = ip->ref; + release(&icache.lock); + if (r == 1) { + // inode has no links and no other references: truncate and free. + itrunc(ip); + ip->type = 0; + iupdate(ip); + ip->valid = 0; + } + } + releasesleep(&ip->lock); + + acquire(&icache.lock); + ip->ref--; + release(&icache.lock); +} + +// Common idiom: unlock, then put. +void iunlockput(struct inode *ip) { + iunlock(ip); + iput(ip); +} + + +// Inode content +// +// The content (data) associated with each inode is stored +// in blocks on the disk. The first NDIRECT block numbers +// are listed in ip->addrs[]. The next NINDIRECT blocks are +// listed in block ip->addrs[NDIRECT]. + +// Return the disk block address of the nth block in inode ip. +// If there is no such block, bmap allocates one. +static uint bmap(struct inode *ip, uint bn) { + uint addr, *a; + struct buf *bp; + + if (bn < NDIRECT) { + if ((addr = ip->addrs[bn]) == 0) { + ip->addrs[bn] = addr = balloc(ip->dev); + } + return addr; + } + bn -= NDIRECT; + + if (bn < NINDIRECT) { + // Load indirect block, allocating if necessary. + if ((addr = ip->addrs[NDIRECT]) == 0) { + ip->addrs[NDIRECT] = addr = balloc(ip->dev); + } + bp = bread(ip->dev, addr); + a = (uint*)bp->data; + if ((addr = a[bn]) == 0) { + a[bn] = addr = balloc(ip->dev); + log_write(bp); + } + brelse(bp); + return addr; + } + + panic("bmap: out of range"); +} + +// Truncate inode (discard contents). +// Only called when the inode has no links +// to it (no directory entries referring to it) +// and has no in-memory reference to it (is +// not an open file or current directory). +static void itrunc(struct inode *ip) { + int i, j; + struct buf *bp; + uint *a; + + for (i = 0; i < NDIRECT; i++) { + if (ip->addrs[i]) { + bfree(ip->dev, ip->addrs[i]); + ip->addrs[i] = 0; + } + } + + if (ip->addrs[NDIRECT]) { + bp = bread(ip->dev, ip->addrs[NDIRECT]); + a = (uint*)bp->data; + for (j = 0; j < NINDIRECT; j++) { + if (a[j]) { + bfree(ip->dev, a[j]); + } + } + brelse(bp); + bfree(ip->dev, ip->addrs[NDIRECT]); + ip->addrs[NDIRECT] = 0; + } + + ip->size = 0; + iupdate(ip); +} + +// Copy stat information from inode. +// Caller must hold ip->lock. +void stati(struct inode *ip, struct stat *st) { + st->dev = ip->dev; + st->ino = ip->inum; + st->type = ip->type; + st->nlink = ip->nlink; + st->size = ip->size; +} + + +// Read data from inode. +// Caller must hold ip->lock. +int readi(struct inode *ip, char *dst, uint off, uint n) { + uint tot, m; + struct buf *bp; + + if (ip->type == T_DEV) { + if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read) { + return -1; + } + return devsw[ip->major].read(ip, dst, n); + } + + if (off > ip->size || off + n < off) { + return -1; + } + if (off + n > ip->size) { + n = ip->size - off; + } + + for (tot = 0; tot < n; tot += m, off += m, dst += m) { + bp = bread(ip->dev, bmap(ip, off / BSIZE)); + m = min(n - tot, BSIZE - off % BSIZE); + memmove(dst, bp->data + off % BSIZE, m); + brelse(bp); + } + return n; +} + +// Write data to inode. +// Caller must hold ip->lock. +int writei(struct inode *ip, char *src, uint off, uint n) { + uint tot, m; + struct buf *bp; + + if (ip->type == T_DEV) { + if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write) { + return -1; + } + return devsw[ip->major].write(ip, src, n); + } + + if (off > ip->size || off + n < off) { + return -1; + } + if (off + n > MAXFILE * BSIZE) { + return -1; + } + + for (tot = 0; tot < n; tot += m, off += m, src += m) { + bp = bread(ip->dev, bmap(ip, off / BSIZE)); + m = min(n - tot, BSIZE - off % BSIZE); + memmove(bp->data + off % BSIZE, src, m); + log_write(bp); + brelse(bp); + } + + if (n > 0 && off > ip->size) { + ip->size = off; + iupdate(ip); + } + return n; +} + + +// Directories + +int namecmp(const char *s, const char *t) { + return strncmp(s, t, DIRSIZ); +} + +// Look for a directory entry in a directory. +// If found, set *poff to byte offset of entry. +struct inode* dirlookup(struct inode *dp, char *name, uint *poff) { + uint off, inum; + struct dirent de; + + if (dp->type != T_DIR) { + panic("dirlookup not DIR"); + } + + for (off = 0; off < dp->size; off += sizeof(de)) { + if (readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { + panic("dirlookup read"); + } + if (de.inum == 0) { + continue; + } + if (namecmp(name, de.name) == 0) { + // entry matches path element + if (poff) { + *poff = off; + } + inum = de.inum; + return iget(dp->dev, inum); + } + } + + return 0; +} + +// Write a new directory entry (name, inum) into the directory dp. +int dirlink(struct inode *dp, char *name, uint inum) { + int off; + struct dirent de; + struct inode *ip; + + // Check that name is not present. + if ((ip = dirlookup(dp, name, 0)) != 0) { + iput(ip); + return -1; + } + + // Look for an empty dirent. + for (off = 0; off < dp->size; off += sizeof(de)) { + if (readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { + panic("dirlink read"); + } + if (de.inum == 0) { + break; + } + } + + strncpy(de.name, name, DIRSIZ); + de.inum = inum; + if (writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { + panic("dirlink"); + } + + return 0; +} + + +// Paths + +// Copy the next path element from path into name. +// Return a pointer to the element following the copied one. +// The returned path has no leading slashes, +// so the caller can check *path=='\0' to see if the name is the last one. +// If no name to remove, return 0. +// +// Examples: +// skipelem("a/bb/c", name) = "bb/c", setting name = "a" +// skipelem("///a//bb", name) = "bb", setting name = "a" +// skipelem("a", name) = "", setting name = "a" +// skipelem("", name) = skipelem("////", name) = 0 +// +static char* skipelem(char *path, char *name) { + char *s; + int len; + + while (*path == '/') { + path++; + } + if (*path == 0) { + return 0; + } + s = path; + while (*path != '/' && *path != 0) { + path++; + } + len = path - s; + if (len >= DIRSIZ) { + memmove(name, s, DIRSIZ); + } + else { + memmove(name, s, len); + name[len] = 0; + } + while (*path == '/') { + path++; + } + return path; +} + +// Look up and return the inode for a path name. +// If parent != 0, return the inode for the parent and copy the final +// path element into name, which must have room for DIRSIZ bytes. +// Must be called inside a transaction since it calls iput(). +static struct inode* namex(char *path, int nameiparent, char *name) { + struct inode *ip, *next; + + if (*path == '/') { + ip = iget(ROOTDEV, ROOTINO); + } + else { + ip = idup(myproc()->cwd); + } + + while ((path = skipelem(path, name)) != 0) { + ilock(ip); + if (ip->type != T_DIR) { + iunlockput(ip); + return 0; + } + if (nameiparent && *path == '\0') { + // Stop one level early. + iunlock(ip); + return ip; + } + if ((next = dirlookup(ip, name, 0)) == 0) { + iunlockput(ip); + return 0; + } + iunlockput(ip); + ip = next; + } + if (nameiparent) { + iput(ip); + return 0; + } + return ip; +} + +struct inode* namei(char *path) { + char name[DIRSIZ]; + return namex(path, 0, name); +} + +struct inode*nameiparent(char *path, char *name) { + return namex(path, 1, name); +} diff --git a/fs.d b/fs.d new file mode 100644 index 0000000..a1d05cc --- /dev/null +++ b/fs.d @@ -0,0 +1,2 @@ +fs.o: fs.c /usr/include/stdc-predef.h types.h defs.h param.h stat.h mmu.h \ + proc.h spinlock.h sleeplock.h fs.h buf.h file.h diff --git a/fs.h b/fs.h new file mode 100644 index 0000000..3651c7b --- /dev/null +++ b/fs.h @@ -0,0 +1,57 @@ +// On-disk file system format. +// Both the kernel and user programs use this header file. + + +#define ROOTINO 1 // root i-number +#define BSIZE 512 // block size + +// Disk layout: +// [ boot block | super block | log | inode blocks | +// free bit map | data blocks] +// +// mkfs computes the super block and builds an initial file system. The +// super block describes the disk layout: +struct superblock { + uint size; // Size of file system image (blocks) + uint nblocks; // Number of data blocks + uint ninodes; // Number of inodes. + uint nlog; // Number of log blocks + uint logstart; // Block number of first log block + uint inodestart; // Block number of first inode block + uint bmapstart; // Block number of first free map block +}; + +#define NDIRECT 12 +#define NINDIRECT (BSIZE / sizeof(uint)) +#define MAXFILE (NDIRECT + NINDIRECT) + +// On-disk inode structure +struct dinode { + short type; // File type + short major; // Major device number (T_DEV only) + short minor; // Minor device number (T_DEV only) + short nlink; // Number of links to inode in file system + uint size; // Size of file (bytes) + uint addrs[NDIRECT + 1]; // Data block addresses +}; + +// Inodes per block. +#define IPB (BSIZE / sizeof(struct dinode)) + +// Block containing inode i +#define IBLOCK(i, sb) ((i) / IPB + sb.inodestart) + +// Bitmap bits per block +#define BPB (BSIZE * 8) + +// Block of free map containing bit for block b +#define BBLOCK(b, sb) (b / BPB + sb.bmapstart) + +// Directory is a file containing a sequence of dirent structures. +#define DIRSIZ 14 + +struct dirent { + ushort inum; + char name[DIRSIZ]; +}; + diff --git a/fs.img b/fs.img new file mode 100644 index 0000000..ab94c57 --- /dev/null +++ b/fs.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d0c3858c578bd9d627937e9b5fff66f725fb40f4a85411a7b20a6ce82417182 +size 512000 diff --git a/fs.o b/fs.o new file mode 100644 index 0000000..4c93a34 Binary files /dev/null and b/fs.o differ diff --git a/gdbutil b/gdbutil new file mode 100644 index 0000000..e0c362f --- /dev/null +++ b/gdbutil @@ -0,0 +1,291 @@ +# -*- gdb-script -*- + +# Utility functions to pretty-print x86 segment/interrupt descriptors. +# To load this file, run "source gdbutil" in gdb. +# printdesc and printdescs are the main entry points. + +# IA32 2007, Volume 3A, Table 3-2 +set $STS_T16A = 0x1 +set $STS_LDT = 0x2 +set $STS_T16B = 0x3 +set $STS_CG16 = 0x4 +set $STS_TG = 0x5 +set $STS_IG16 = 0x6 +set $STS_TG16 = 0x7 +set $STS_T32A = 0x9 +set $STS_T32B = 0xB +set $STS_CG32 = 0xC +set $STS_IG32 = 0xE +set $STS_TG32 = 0xF + +define outputsts + while 1 + if $arg0 == $STS_T16A + echo STS_T16A + loop_break + end + if $arg0 == $STS_LDT + echo STS_LDT\ + loop_break + end + if $arg0 == $STS_T16B + echo STS_T16B + loop_break + end + if $arg0 == $STS_CG16 + echo STS_CG16 + loop_break + end + if $arg0 == $STS_TG + echo STS_TG\ \ + loop_break + end + if $arg0 == $STS_IG16 + echo STS_IG16 + loop_break + end + if $arg0 == $STS_TG16 + echo STS_TG16 + loop_break + end + if $arg0 == $STS_T32A + echo STS_T32A + loop_break + end + if $arg0 == $STS_T32B + echo STS_T32B + loop_break + end + if $arg0 == $STS_CG32 + echo STS_CG32 + loop_break + end + if $arg0 == $STS_IG32 + echo STS_IG32 + loop_break + end + if $arg0 == $STS_TG32 + echo STS_TG32 + loop_break + end + echo Reserved + loop_break + end +end + +# IA32 2007, Volume 3A, Table 3-1 +set $STA_X = 0x8 +set $STA_E = 0x4 +set $STA_C = 0x4 +set $STA_W = 0x2 +set $STA_R = 0x2 +set $STA_A = 0x1 + +define outputsta + if $arg0 & $STA_X + # Code segment + echo code + if $arg0 & $STA_C + echo |STA_C + end + if $arg0 & $STA_R + echo |STA_R + end + else + # Data segment + echo data + if $arg0 & $STA_E + echo |STA_E + end + if $arg0 & $STA_W + echo |STA_W + end + end + if $arg0 & $STA_A + echo |STA_A + else + printf " " + end +end + +# xv6-specific +set $SEG_KCODE = 1 +set $SEG_KDATA = 2 +set $SEG_KCPU = 3 +set $SEG_UCODE = 4 +set $SEG_UDATA = 5 +set $SEG_TSS = 6 + +define outputcs + if ($arg0 & 4) == 0 + if $arg0 >> 3 == $SEG_KCODE + printf "SEG_KCODE<<3" + end + if $arg0 >> 3 == $SEG_KDATA + printf "SEG_KDATA<<3" + end + if $arg0 >> 3 == $SEG_KCPU + printf "SEG_KCPU<<3" + end + if $arg0 >> 3 == $SEG_UCODE + printf "SEG_UCODE<<3" + end + if $arg0 >> 3 == $SEG_UDATA + printf "SEG_UDATA<<3" + end + if $arg0 >> 3 == $SEG_TSS + printf "SEG_TSS<<3" + end + if ($arg0 >> 3 < 1) + ($arg0 >> 3 > 6) + printf "GDT[%d]", $arg0 >> 3 + end + else + printf "LDT[%d]", $arg0 >> 3 + end + if ($arg0 & 3) > 0 + printf "|" + outputdpl ($arg0&3) + end +end + +define outputdpl + if $arg0 == 0 + printf "DPL_KERN" + else + if $arg0 == 3 + printf "DPL_USER" + else + printf "DPL%d", $arg0 + end + end +end + +define printdesc + if $argc != 1 + echo Usage: printdesc expr + else + _printdesc ((uint*)&($arg0))[0] ((uint*)&($arg0))[1] + printf "\n" + end +end + +document printdesc +Print an x86 segment or gate descriptor. +printdesc EXPR +EXPR must evaluate to a descriptor value. It can be of any C type. +end + +define _printdesc + _printdesc1 $arg0 $arg1 ($arg1>>15&1) ($arg1>>13&3) ($arg1>>12&1) ($arg1>>8&15) +end + +define _printdesc1 + # 2:P 3:DPL 4:S 5:Type + if $arg2 == 0 + printf "P = 0 (Not present)" + else + printf "type = " + if $arg4 == 0 + # System segment + outputsts $arg5 + printf " (0x%x) ", $arg5 + _printsysdesc $arg0 $arg1 $arg5 + else + # Code/data segment + outputsta $arg5 + printf " " + _printsegdesc $arg0 $arg1 + end + + printf " DPL = " + outputdpl $arg3 + printf " (%d)", $arg3 + end +end + +define _printsysdesc + # 2:Type + # GDB's || is buggy + if ($arg2 == $STS_TG) + (($arg2&7) == $STS_IG16) + (($arg2&7) == $STS_TG16) + # Gate descriptor + _printgate $arg2 ($arg0>>16) ($arg0&0xFFFF) ($arg1>>16) + else + # System segment descriptor + _printsegdesc $arg0 $arg1 + end +end + +define _printgate + # IA32 2007, Voume 3A, Figure 5-2 + # 0:Type 1:CS 2:Offset 15..0 3:Offset 31..16 + printf "CS = " + outputcs $arg1 + printf " (%d)", $arg1 + + if (($arg0&7) == $STS_IG16) + (($arg0&7) == $STS_TG16) + printf " Offset = " + output/a $arg3 << 16 | $arg2 + end +end + +define _printsegdesc + # IA32 20007, Volume 3A, Figure 3-8 and Figure 4-1 + _printsegdesc1 ($arg0>>16) ($arg1&0xFF) ($arg1>>24) ($arg0&0xFFFF) ($arg1>>16&15) ($arg1>>23&1) + if ($arg1>>12&1) == 1 + printf " AVL = %d", $arg1>>20&1 + if ($arg1>>11&1) == 0 + # Data segment + if ($arg1>>22&1) == 0 + printf " B = small (0) " + else + printf " B = big (1) " + end + else + # Code segment + printf " D = " + if ($arg1>>22&1) == 0 + printf "16-bit (0)" + else + printf "32-bit (1)" + end + end + end +end + +define _printsegdesc1 + # 0:Base 0..15 1:Base 16..23 2:Base 24..32 3:Limit 0..15 4:Limit 16..19 5:G + printf "base = 0x%08x", $arg0 | ($arg1<<16) | ($arg2<<24) + printf " limit = 0x" + if $arg5 == 0 + printf "%08x", $arg3 | ($arg4<<16) + else + printf "%08x", (($arg3 | ($arg4<<16)) << 12) | 0xFFF + end +end + +define printdescs + if $argc < 1 || $argc > 2 + echo Usage: printdescs expr [count] + else + if $argc == 1 + _printdescs ($arg0) (sizeof($arg0)/sizeof(($arg0)[0])) + else + _printdescs ($arg0) ($arg1) + end + end +end + +document printdescs +Print an array of x86 segment or gate descriptors. +printdescs EXPR [COUNT] +EXPR must evaluate to an array of descriptors. +end + +define _printdescs + set $i = 0 + while $i < $arg1 + printf "[%d] ", $i + printdesc $arg0[$i] + set $i = $i + 1 + end +end diff --git a/gensyscalls.pl b/gensyscalls.pl new file mode 100644 index 0000000..fa040a1 --- /dev/null +++ b/gensyscalls.pl @@ -0,0 +1,104 @@ +#!/usr/bin/perl -w + +# Generate syscall.h, syscalltable.h or usys.S. These are the header and assembly +# files for system calls. +# +# Generating these files from one script avoids them getting out of sync. +# +# Specify an argument of -h to generate syscall.h +# Specify an argument of -c to generate syscalltable.h +# Specify an argument of -a to generate usys.S +# +# Note that you also need to update user.h with the declarations for these functions that +# user programs will use. This ensures that the C compiler generates the correct code to +# push the parameters on to the stack. + +my @syscalls = ( + "fork", + "exit", + "wait", + "pipe", + "read", + "kill", + "exec", + "fstat", + "chdir", + "dup", + "getpid", + "sbrk", + "sleep", + "uptime", + "open", + "write", + "mknod", + "unlink", + "link", + "mkdir", + "close", + "getch", + "greeting", + "shutdown" + ); + +my $i; +if ($#ARGV == -1) +{ + print 'Error: No argument supplied to gensyscalls.pl'; + exit(1); +} +if (($ARGV[0] ne '-h') && ($ARGV[0] ne '-a') && ($ARGV[0] ne '-c')) +{ + print 'Error: Invalid argument to gensyscalls.pl'; + exit(1); +} +if ($ARGV[0] eq '-h'|| $ARGV[0] eq '-c') +{ + print "// Generated by gensyscalls.pl. Do not edit.\n"; + print "// To change syscall numbers or add new syscalls, edit gensyscalls.pl\n"; + print "\n"; +} +else +{ + print "# Generated by gensyscalls.pl. Do not edit.\n"; + print "# To change syscall numbers or add new syscalls, edit gensyscalls.pl\n"; + print "\n"; +} +for ($i = 0; $i < scalar(@syscalls); $i++) +{ + my $index = $i + 1; + if ($ARGV[0] eq '-h') + { + print "#define SYS_$syscalls[$i]\t\t$index\n"; + } + elsif ($ARGV[0] eq '-c') + { + print "extern int sys_$syscalls[$i](void);\n"; + } +} +if ($ARGV[0] eq '-a') +{ + print "#include \"syscall.h\"\n"; + print "#include \"traps.h\"\n"; + print "\n"; + print "#define SYSCALL(name) \\\n"; + print ".globl name; \\\n"; + print "name: \\\n"; + print "\tmovl\t\$SYS_ ## name, \%eax; \\\n"; + print "\tint\t\$T_SYSCALL; \\\n"; + print "\tret\n"; + print "\n"; + for ($i = 0; $i < scalar(@syscalls); $i++) + { + print "SYSCALL($syscalls[$i])\n"; + } +} +elsif ($ARGV[0] eq '-c') +{ + print "\n"; + print "static int(*syscalls[])(void) = {\n"; + for ($i = 0; $i < scalar(@syscalls); $i++) + { + print "[SYS_$syscalls[$i]]\tsys_$syscalls[$i],\n"; + } + print "};\n" +} diff --git a/grep.asm b/grep.asm new file mode 100644 index 0000000..f27bab9 --- /dev/null +++ b/grep.asm @@ -0,0 +1,1583 @@ + +_grep: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: + memmove(buf, p, m); + } + } +} + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: 53 push %ebx + 10: 51 push %ecx + 11: 83 ec 18 sub $0x18,%esp + 14: 8b 01 mov (%ecx),%eax + 16: 8b 59 04 mov 0x4(%ecx),%ebx + 19: 89 45 e4 mov %eax,-0x1c(%ebp) + int fd, i; + char *pattern; + + if (argc <= 1) { + 1c: 83 f8 01 cmp $0x1,%eax + 1f: 7e 6f jle 90 + printf(2, "usage: grep pattern [file ...]\n"); + exit(); + } + pattern = argv[1]; + 21: 8b 43 04 mov 0x4(%ebx),%eax + 24: 83 c3 08 add $0x8,%ebx + + if (argc <= 2) { + 27: 83 7d e4 02 cmpl $0x2,-0x1c(%ebp) + grep(pattern, 0); + exit(); + } + + for (i = 2; i < argc; i++) { + 2b: be 02 00 00 00 mov $0x2,%esi + pattern = argv[1]; + 30: 89 45 e0 mov %eax,-0x20(%ebp) + if (argc <= 2) { + 33: 75 2d jne 62 + 35: eb 6c jmp a3 + 37: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3e: 66 90 xchg %ax,%ax + if ((fd = open(argv[i], 0)) < 0) { + printf(1, "grep: cannot open %s\n", argv[i]); + exit(); + } + grep(pattern, fd); + 40: 83 ec 08 sub $0x8,%esp + for (i = 2; i < argc; i++) { + 43: 83 c6 01 add $0x1,%esi + 46: 83 c3 04 add $0x4,%ebx + grep(pattern, fd); + 49: 50 push %eax + 4a: ff 75 e0 push -0x20(%ebp) + 4d: e8 7e 01 00 00 call 1d0 + close(fd); + 52: 89 3c 24 mov %edi,(%esp) + 55: e8 01 06 00 00 call 65b + for (i = 2; i < argc; i++) { + 5a: 83 c4 10 add $0x10,%esp + 5d: 39 75 e4 cmp %esi,-0x1c(%ebp) + 60: 7e 29 jle 8b + if ((fd = open(argv[i], 0)) < 0) { + 62: 83 ec 08 sub $0x8,%esp + 65: 6a 00 push $0x0 + 67: ff 33 push (%ebx) + 69: e8 bd 05 00 00 call 62b + 6e: 83 c4 10 add $0x10,%esp + 71: 89 c7 mov %eax,%edi + 73: 85 c0 test %eax,%eax + 75: 79 c9 jns 40 + printf(1, "grep: cannot open %s\n", argv[i]); + 77: 50 push %eax + 78: ff 33 push (%ebx) + 7a: 68 78 0a 00 00 push $0xa78 + 7f: 6a 01 push $0x1 + 81: e8 aa 06 00 00 call 730 + exit(); + 86: e8 38 05 00 00 call 5c3 + } + exit(); + 8b: e8 33 05 00 00 call 5c3 + printf(2, "usage: grep pattern [file ...]\n"); + 90: 51 push %ecx + 91: 51 push %ecx + 92: 68 58 0a 00 00 push $0xa58 + 97: 6a 02 push $0x2 + 99: e8 92 06 00 00 call 730 + exit(); + 9e: e8 20 05 00 00 call 5c3 + grep(pattern, 0); + a3: 52 push %edx + a4: 52 push %edx + a5: 6a 00 push $0x0 + a7: 50 push %eax + a8: e8 23 01 00 00 call 1d0 + exit(); + ad: e8 11 05 00 00 call 5c3 + b2: 66 90 xchg %ax,%ax + b4: 66 90 xchg %ax,%ax + b6: 66 90 xchg %ax,%ax + b8: 66 90 xchg %ax,%ax + ba: 66 90 xchg %ax,%ax + bc: 66 90 xchg %ax,%ax + be: 66 90 xchg %ax,%ax + +000000c0 : + while (*text++ != '\0'); + return 0; +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text){ + c0: 55 push %ebp + c1: 89 e5 mov %esp,%ebp + c3: 57 push %edi + c4: 56 push %esi + c5: 53 push %ebx + c6: 83 ec 0c sub $0xc,%esp + c9: 8b 75 08 mov 0x8(%ebp),%esi + cc: 8b 7d 0c mov 0xc(%ebp),%edi + if (re[0] == '\0') { + cf: 0f b6 06 movzbl (%esi),%eax + d2: 84 c0 test %al,%al + d4: 75 2d jne 103 + d6: e9 7d 00 00 00 jmp 158 + db: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + df: 90 nop + } + if (re[1] == '*') { + return matchstar(re[0], re + 2, text); + } + if (re[0] == '$' && re[1] == '\0') { + return *text == '\0'; + e0: 0f b6 0f movzbl (%edi),%ecx + if (re[0] == '$' && re[1] == '\0') { + e3: 80 fb 24 cmp $0x24,%bl + e6: 75 04 jne ec + e8: 84 c0 test %al,%al + ea: 74 79 je 165 + } + if (*text != '\0' && (re[0] == '.' || re[0] == *text)) { + ec: 84 c9 test %cl,%cl + ee: 74 58 je 148 + f0: 38 d9 cmp %bl,%cl + f2: 74 05 je f9 + f4: 80 fb 2e cmp $0x2e,%bl + f7: 75 4f jne 148 + return matchhere(re + 1, text + 1); + f9: 83 c7 01 add $0x1,%edi + fc: 83 c6 01 add $0x1,%esi + if (re[0] == '\0') { + ff: 84 c0 test %al,%al + 101: 74 55 je 158 + if (re[1] == '*') { + 103: 0f be d8 movsbl %al,%ebx + 106: 0f b6 46 01 movzbl 0x1(%esi),%eax + 10a: 3c 2a cmp $0x2a,%al + 10c: 75 d2 jne e0 + return matchstar(re[0], re + 2, text); + 10e: 83 c6 02 add $0x2,%esi + } + return 0; +} + +// matchstar: search for c*re at beginning of text +int matchstar(int c, char *re, char *text) { + 111: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + do { // a * matches zero or more instances + if (matchhere(re, text)) { + 118: 83 ec 08 sub $0x8,%esp + 11b: 57 push %edi + 11c: 56 push %esi + 11d: e8 9e ff ff ff call c0 + 122: 83 c4 10 add $0x10,%esp + 125: 85 c0 test %eax,%eax + 127: 75 2f jne 158 + return 1; + } + } + while (*text != '\0' && (*text++ == c || c == '.')); + 129: 0f be 17 movsbl (%edi),%edx + 12c: 84 d2 test %dl,%dl + 12e: 74 0c je 13c + 130: 83 c7 01 add $0x1,%edi + 133: 83 fb 2e cmp $0x2e,%ebx + 136: 74 e0 je 118 + 138: 39 da cmp %ebx,%edx + 13a: 74 dc je 118 +} + 13c: 8d 65 f4 lea -0xc(%ebp),%esp + 13f: 5b pop %ebx + 140: 5e pop %esi + 141: 5f pop %edi + 142: 5d pop %ebp + 143: c3 ret + 144: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 148: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 14b: 31 c0 xor %eax,%eax +} + 14d: 5b pop %ebx + 14e: 5e pop %esi + 14f: 5f pop %edi + 150: 5d pop %ebp + 151: c3 ret + 152: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + 158: 8d 65 f4 lea -0xc(%ebp),%esp + return 1; + 15b: b8 01 00 00 00 mov $0x1,%eax +} + 160: 5b pop %ebx + 161: 5e pop %esi + 162: 5f pop %edi + 163: 5d pop %ebp + 164: c3 ret + return *text == '\0'; + 165: 31 c0 xor %eax,%eax + 167: 84 c9 test %cl,%cl + 169: 0f 94 c0 sete %al + 16c: eb ce jmp 13c + 16e: 66 90 xchg %ax,%ax + +00000170 : +int match(char *re, char *text) { + 170: 55 push %ebp + 171: 89 e5 mov %esp,%ebp + 173: 56 push %esi + 174: 53 push %ebx + 175: 8b 5d 08 mov 0x8(%ebp),%ebx + 178: 8b 75 0c mov 0xc(%ebp),%esi + if (re[0] == '^') { + 17b: 80 3b 5e cmpb $0x5e,(%ebx) + 17e: 75 11 jne 191 + 180: eb 2e jmp 1b0 + 182: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + while (*text++ != '\0'); + 188: 83 c6 01 add $0x1,%esi + 18b: 80 7e ff 00 cmpb $0x0,-0x1(%esi) + 18f: 74 16 je 1a7 + if (matchhere(re, text)) { + 191: 83 ec 08 sub $0x8,%esp + 194: 56 push %esi + 195: 53 push %ebx + 196: e8 25 ff ff ff call c0 + 19b: 83 c4 10 add $0x10,%esp + 19e: 85 c0 test %eax,%eax + 1a0: 74 e6 je 188 + return 1; + 1a2: b8 01 00 00 00 mov $0x1,%eax +} + 1a7: 8d 65 f8 lea -0x8(%ebp),%esp + 1aa: 5b pop %ebx + 1ab: 5e pop %esi + 1ac: 5d pop %ebp + 1ad: c3 ret + 1ae: 66 90 xchg %ax,%ax + return matchhere(re + 1, text); + 1b0: 83 c3 01 add $0x1,%ebx + 1b3: 89 5d 08 mov %ebx,0x8(%ebp) +} + 1b6: 8d 65 f8 lea -0x8(%ebp),%esp + 1b9: 5b pop %ebx + 1ba: 5e pop %esi + 1bb: 5d pop %ebp + return matchhere(re + 1, text); + 1bc: e9 ff fe ff ff jmp c0 + 1c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1cf: 90 nop + +000001d0 : +void grep(char *pattern, int fd) { + 1d0: 55 push %ebp + 1d1: 89 e5 mov %esp,%ebp + 1d3: 57 push %edi + 1d4: 56 push %esi + 1d5: 53 push %ebx + 1d6: 83 ec 1c sub $0x1c,%esp + 1d9: 8b 7d 08 mov 0x8(%ebp),%edi + m = 0; + 1dc: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + return matchhere(re + 1, text); + 1e3: 8d 47 01 lea 0x1(%edi),%eax + 1e6: 89 45 d8 mov %eax,-0x28(%ebp) + 1e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + while ((n = read(fd, buf + m, sizeof(buf) - m - 1)) > 0) { + 1f0: 8b 4d dc mov -0x24(%ebp),%ecx + 1f3: b8 ff 03 00 00 mov $0x3ff,%eax + 1f8: 83 ec 04 sub $0x4,%esp + 1fb: 29 c8 sub %ecx,%eax + 1fd: 50 push %eax + 1fe: 8d 81 a0 0e 00 00 lea 0xea0(%ecx),%eax + 204: 50 push %eax + 205: ff 75 0c push 0xc(%ebp) + 208: e8 ce 03 00 00 call 5db + 20d: 83 c4 10 add $0x10,%esp + 210: 85 c0 test %eax,%eax + 212: 0f 8e e5 00 00 00 jle 2fd + m += n; + 218: 01 45 dc add %eax,-0x24(%ebp) + 21b: 8b 4d dc mov -0x24(%ebp),%ecx + p = buf; + 21e: c7 45 e4 a0 0e 00 00 movl $0xea0,-0x1c(%ebp) + buf[m] = '\0'; + 225: c6 81 a0 0e 00 00 00 movb $0x0,0xea0(%ecx) + while ((q = strchr(p, '\n')) != 0) { + 22c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 230: 83 ec 08 sub $0x8,%esp + 233: 6a 0a push $0xa + 235: ff 75 e4 push -0x1c(%ebp) + 238: e8 13 02 00 00 call 450 + 23d: 83 c4 10 add $0x10,%esp + 240: 89 c3 mov %eax,%ebx + 242: 85 c0 test %eax,%eax + 244: 74 72 je 2b8 + *q = 0; + 246: c6 03 00 movb $0x0,(%ebx) + write(1, p, q + 1 - p); + 249: 8d 43 01 lea 0x1(%ebx),%eax + if (re[0] == '^') { + 24c: 80 3f 5e cmpb $0x5e,(%edi) + write(1, p, q + 1 - p); + 24f: 89 45 e0 mov %eax,-0x20(%ebp) + 252: 8b 75 e4 mov -0x1c(%ebp),%esi + if (re[0] == '^') { + 255: 75 12 jne 269 + 257: eb 47 jmp 2a0 + 259: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + while (*text++ != '\0'); + 260: 83 c6 01 add $0x1,%esi + 263: 80 7e ff 00 cmpb $0x0,-0x1(%esi) + 267: 74 2b je 294 + if (matchhere(re, text)) { + 269: 83 ec 08 sub $0x8,%esp + 26c: 56 push %esi + 26d: 57 push %edi + 26e: e8 4d fe ff ff call c0 + 273: 83 c4 10 add $0x10,%esp + 276: 85 c0 test %eax,%eax + 278: 74 e6 je 260 + write(1, p, q + 1 - p); + 27a: 8b 55 e4 mov -0x1c(%ebp),%edx + 27d: 8b 45 e0 mov -0x20(%ebp),%eax + 280: 83 ec 04 sub $0x4,%esp + *q = '\n'; + 283: c6 03 0a movb $0xa,(%ebx) + write(1, p, q + 1 - p); + 286: 29 d0 sub %edx,%eax + 288: 50 push %eax + 289: 52 push %edx + 28a: 6a 01 push $0x1 + 28c: e8 a2 03 00 00 call 633 + 291: 83 c4 10 add $0x10,%esp + p = q + 1; + 294: 8b 45 e0 mov -0x20(%ebp),%eax + 297: 89 45 e4 mov %eax,-0x1c(%ebp) + 29a: eb 94 jmp 230 + 29c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + return matchhere(re + 1, text); + 2a0: 83 ec 08 sub $0x8,%esp + 2a3: 56 push %esi + 2a4: ff 75 d8 push -0x28(%ebp) + 2a7: e8 14 fe ff ff call c0 + 2ac: 83 c4 10 add $0x10,%esp + if (match(pattern, p)) { + 2af: 85 c0 test %eax,%eax + 2b1: 74 e1 je 294 + 2b3: eb c5 jmp 27a + 2b5: 8d 76 00 lea 0x0(%esi),%esi + if (p == buf) { + 2b8: 8b 55 e4 mov -0x1c(%ebp),%edx + 2bb: 81 fa a0 0e 00 00 cmp $0xea0,%edx + 2c1: 74 2e je 2f1 + if (m > 0) { + 2c3: 8b 4d dc mov -0x24(%ebp),%ecx + 2c6: 85 c9 test %ecx,%ecx + 2c8: 0f 8e 22 ff ff ff jle 1f0 + m -= p - buf; + 2ce: 89 d0 mov %edx,%eax + memmove(buf, p, m); + 2d0: 83 ec 04 sub $0x4,%esp + m -= p - buf; + 2d3: 2d a0 0e 00 00 sub $0xea0,%eax + 2d8: 29 c1 sub %eax,%ecx + memmove(buf, p, m); + 2da: 51 push %ecx + 2db: 52 push %edx + 2dc: 68 a0 0e 00 00 push $0xea0 + m -= p - buf; + 2e1: 89 4d dc mov %ecx,-0x24(%ebp) + memmove(buf, p, m); + 2e4: e8 a7 02 00 00 call 590 + 2e9: 83 c4 10 add $0x10,%esp + 2ec: e9 ff fe ff ff jmp 1f0 + m = 0; + 2f1: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 2f8: e9 f3 fe ff ff jmp 1f0 +} + 2fd: 8d 65 f4 lea -0xc(%ebp),%esp + 300: 5b pop %ebx + 301: 5e pop %esi + 302: 5f pop %edi + 303: 5d pop %ebp + 304: c3 ret + 305: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 30c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000310 : +int matchstar(int c, char *re, char *text) { + 310: 55 push %ebp + 311: 89 e5 mov %esp,%ebp + 313: 57 push %edi + 314: 56 push %esi + 315: 53 push %ebx + 316: 83 ec 0c sub $0xc,%esp + 319: 8b 5d 08 mov 0x8(%ebp),%ebx + 31c: 8b 75 0c mov 0xc(%ebp),%esi + 31f: 8b 7d 10 mov 0x10(%ebp),%edi + 322: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (matchhere(re, text)) { + 328: 83 ec 08 sub $0x8,%esp + 32b: 57 push %edi + 32c: 56 push %esi + 32d: e8 8e fd ff ff call c0 + 332: 83 c4 10 add $0x10,%esp + 335: 85 c0 test %eax,%eax + 337: 75 1f jne 358 + while (*text != '\0' && (*text++ == c || c == '.')); + 339: 0f be 17 movsbl (%edi),%edx + 33c: 84 d2 test %dl,%dl + 33e: 74 0c je 34c + 340: 83 c7 01 add $0x1,%edi + 343: 39 da cmp %ebx,%edx + 345: 74 e1 je 328 + 347: 83 fb 2e cmp $0x2e,%ebx + 34a: 74 dc je 328 +} + 34c: 8d 65 f4 lea -0xc(%ebp),%esp + 34f: 5b pop %ebx + 350: 5e pop %esi + 351: 5f pop %edi + 352: 5d pop %ebp + 353: c3 ret + 354: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 358: 8d 65 f4 lea -0xc(%ebp),%esp + return 1; + 35b: b8 01 00 00 00 mov $0x1,%eax +} + 360: 5b pop %ebx + 361: 5e pop %esi + 362: 5f pop %edi + 363: 5d pop %ebp + 364: c3 ret + 365: 66 90 xchg %ax,%ax + 367: 66 90 xchg %ax,%ax + 369: 66 90 xchg %ax,%ax + 36b: 66 90 xchg %ax,%ax + 36d: 66 90 xchg %ax,%ax + 36f: 90 nop + +00000370 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 370: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 371: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 373: 89 e5 mov %esp,%ebp + 375: 53 push %ebx + 376: 8b 4d 08 mov 0x8(%ebp),%ecx + 379: 8b 5d 0c mov 0xc(%ebp),%ebx + 37c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 380: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 384: 88 14 01 mov %dl,(%ecx,%eax,1) + 387: 83 c0 01 add $0x1,%eax + 38a: 84 d2 test %dl,%dl + 38c: 75 f2 jne 380 + ; + } + return os; +} + 38e: 8b 5d fc mov -0x4(%ebp),%ebx + 391: 89 c8 mov %ecx,%eax + 393: c9 leave + 394: c3 ret + 395: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 39c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000003a0 : + +int strcmp(const char *p, const char *q) { + 3a0: 55 push %ebp + 3a1: 89 e5 mov %esp,%ebp + 3a3: 53 push %ebx + 3a4: 8b 55 08 mov 0x8(%ebp),%edx + 3a7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 3aa: 0f b6 02 movzbl (%edx),%eax + 3ad: 84 c0 test %al,%al + 3af: 75 17 jne 3c8 + 3b1: eb 3a jmp 3ed + 3b3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 3b7: 90 nop + 3b8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 3bc: 83 c2 01 add $0x1,%edx + 3bf: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 3c2: 84 c0 test %al,%al + 3c4: 74 1a je 3e0 + p++, q++; + 3c6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 3c8: 0f b6 19 movzbl (%ecx),%ebx + 3cb: 38 c3 cmp %al,%bl + 3cd: 74 e9 je 3b8 + } + return (uchar) * p - (uchar) * q; + 3cf: 29 d8 sub %ebx,%eax +} + 3d1: 8b 5d fc mov -0x4(%ebp),%ebx + 3d4: c9 leave + 3d5: c3 ret + 3d6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3dd: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 3e0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 3e4: 31 c0 xor %eax,%eax + 3e6: 29 d8 sub %ebx,%eax +} + 3e8: 8b 5d fc mov -0x4(%ebp),%ebx + 3eb: c9 leave + 3ec: c3 ret + return (uchar) * p - (uchar) * q; + 3ed: 0f b6 19 movzbl (%ecx),%ebx + 3f0: 31 c0 xor %eax,%eax + 3f2: eb db jmp 3cf + 3f4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3fb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 3ff: 90 nop + +00000400 : + +uint strlen(const char *s) { + 400: 55 push %ebp + 401: 89 e5 mov %esp,%ebp + 403: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 406: 80 3a 00 cmpb $0x0,(%edx) + 409: 74 15 je 420 + 40b: 31 c0 xor %eax,%eax + 40d: 8d 76 00 lea 0x0(%esi),%esi + 410: 83 c0 01 add $0x1,%eax + 413: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 417: 89 c1 mov %eax,%ecx + 419: 75 f5 jne 410 + ; + } + return n; +} + 41b: 89 c8 mov %ecx,%eax + 41d: 5d pop %ebp + 41e: c3 ret + 41f: 90 nop + for (n = 0; s[n]; n++) { + 420: 31 c9 xor %ecx,%ecx +} + 422: 5d pop %ebp + 423: 89 c8 mov %ecx,%eax + 425: c3 ret + 426: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 42d: 8d 76 00 lea 0x0(%esi),%esi + +00000430 : + +void* memset(void *dst, int c, uint n) { + 430: 55 push %ebp + 431: 89 e5 mov %esp,%ebp + 433: 57 push %edi + 434: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 437: 8b 4d 10 mov 0x10(%ebp),%ecx + 43a: 8b 45 0c mov 0xc(%ebp),%eax + 43d: 89 d7 mov %edx,%edi + 43f: fc cld + 440: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 442: 8b 7d fc mov -0x4(%ebp),%edi + 445: 89 d0 mov %edx,%eax + 447: c9 leave + 448: c3 ret + 449: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000450 : + +char* strchr(const char *s, char c) { + 450: 55 push %ebp + 451: 89 e5 mov %esp,%ebp + 453: 8b 45 08 mov 0x8(%ebp),%eax + 456: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 45a: 0f b6 10 movzbl (%eax),%edx + 45d: 84 d2 test %dl,%dl + 45f: 75 12 jne 473 + 461: eb 1d jmp 480 + 463: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 467: 90 nop + 468: 0f b6 50 01 movzbl 0x1(%eax),%edx + 46c: 83 c0 01 add $0x1,%eax + 46f: 84 d2 test %dl,%dl + 471: 74 0d je 480 + if (*s == c) { + 473: 38 d1 cmp %dl,%cl + 475: 75 f1 jne 468 + return (char*)s; + } + } + return 0; +} + 477: 5d pop %ebp + 478: c3 ret + 479: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 480: 31 c0 xor %eax,%eax +} + 482: 5d pop %ebp + 483: c3 ret + 484: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 48b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 48f: 90 nop + +00000490 : + +char* gets(char *buf, int max) { + 490: 55 push %ebp + 491: 89 e5 mov %esp,%ebp + 493: 57 push %edi + 494: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 495: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 498: 53 push %ebx + for (i = 0; i + 1 < max;) { + 499: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 49b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 49e: eb 27 jmp 4c7 + cc = read(0, &c, 1); + 4a0: 83 ec 04 sub $0x4,%esp + 4a3: 6a 01 push $0x1 + 4a5: 57 push %edi + 4a6: 6a 00 push $0x0 + 4a8: e8 2e 01 00 00 call 5db + if (cc < 1) { + 4ad: 83 c4 10 add $0x10,%esp + 4b0: 85 c0 test %eax,%eax + 4b2: 7e 1d jle 4d1 + break; + } + buf[i++] = c; + 4b4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 4b8: 8b 55 08 mov 0x8(%ebp),%edx + 4bb: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 4bf: 3c 0a cmp $0xa,%al + 4c1: 74 1d je 4e0 + 4c3: 3c 0d cmp $0xd,%al + 4c5: 74 19 je 4e0 + for (i = 0; i + 1 < max;) { + 4c7: 89 de mov %ebx,%esi + 4c9: 83 c3 01 add $0x1,%ebx + 4cc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 4cf: 7c cf jl 4a0 + break; + } + } + buf[i] = '\0'; + 4d1: 8b 45 08 mov 0x8(%ebp),%eax + 4d4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 4d8: 8d 65 f4 lea -0xc(%ebp),%esp + 4db: 5b pop %ebx + 4dc: 5e pop %esi + 4dd: 5f pop %edi + 4de: 5d pop %ebp + 4df: c3 ret + buf[i] = '\0'; + 4e0: 8b 45 08 mov 0x8(%ebp),%eax + 4e3: 89 de mov %ebx,%esi + 4e5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 4e9: 8d 65 f4 lea -0xc(%ebp),%esp + 4ec: 5b pop %ebx + 4ed: 5e pop %esi + 4ee: 5f pop %edi + 4ef: 5d pop %ebp + 4f0: c3 ret + 4f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4f8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4ff: 90 nop + +00000500 : + +int stat(const char *n, struct stat *st) { + 500: 55 push %ebp + 501: 89 e5 mov %esp,%ebp + 503: 56 push %esi + 504: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 505: 83 ec 08 sub $0x8,%esp + 508: 6a 00 push $0x0 + 50a: ff 75 08 push 0x8(%ebp) + 50d: e8 19 01 00 00 call 62b + if (fd < 0) { + 512: 83 c4 10 add $0x10,%esp + 515: 85 c0 test %eax,%eax + 517: 78 27 js 540 + return -1; + } + r = fstat(fd, st); + 519: 83 ec 08 sub $0x8,%esp + 51c: ff 75 0c push 0xc(%ebp) + 51f: 89 c3 mov %eax,%ebx + 521: 50 push %eax + 522: e8 cc 00 00 00 call 5f3 + close(fd); + 527: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 52a: 89 c6 mov %eax,%esi + close(fd); + 52c: e8 2a 01 00 00 call 65b + return r; + 531: 83 c4 10 add $0x10,%esp +} + 534: 8d 65 f8 lea -0x8(%ebp),%esp + 537: 89 f0 mov %esi,%eax + 539: 5b pop %ebx + 53a: 5e pop %esi + 53b: 5d pop %ebp + 53c: c3 ret + 53d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 540: be ff ff ff ff mov $0xffffffff,%esi + 545: eb ed jmp 534 + 547: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 54e: 66 90 xchg %ax,%ax + +00000550 : + +int atoi(const char *s) { + 550: 55 push %ebp + 551: 89 e5 mov %esp,%ebp + 553: 53 push %ebx + 554: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 557: 0f be 02 movsbl (%edx),%eax + 55a: 8d 48 d0 lea -0x30(%eax),%ecx + 55d: 80 f9 09 cmp $0x9,%cl + n = 0; + 560: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 565: 77 1e ja 585 + 567: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 56e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 570: 83 c2 01 add $0x1,%edx + 573: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 576: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 57a: 0f be 02 movsbl (%edx),%eax + 57d: 8d 58 d0 lea -0x30(%eax),%ebx + 580: 80 fb 09 cmp $0x9,%bl + 583: 76 eb jbe 570 + } + return n; +} + 585: 8b 5d fc mov -0x4(%ebp),%ebx + 588: 89 c8 mov %ecx,%eax + 58a: c9 leave + 58b: c3 ret + 58c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000590 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 590: 55 push %ebp + 591: 89 e5 mov %esp,%ebp + 593: 57 push %edi + 594: 8b 45 10 mov 0x10(%ebp),%eax + 597: 8b 55 08 mov 0x8(%ebp),%edx + 59a: 56 push %esi + 59b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 59e: 85 c0 test %eax,%eax + 5a0: 7e 13 jle 5b5 + 5a2: 01 d0 add %edx,%eax + dst = vdst; + 5a4: 89 d7 mov %edx,%edi + 5a6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5ad: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 5b0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 5b1: 39 f8 cmp %edi,%eax + 5b3: 75 fb jne 5b0 + } + return vdst; +} + 5b5: 5e pop %esi + 5b6: 89 d0 mov %edx,%eax + 5b8: 5f pop %edi + 5b9: 5d pop %ebp + 5ba: c3 ret + +000005bb : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 5bb: b8 01 00 00 00 mov $0x1,%eax + 5c0: cd 40 int $0x40 + 5c2: c3 ret + +000005c3 : +SYSCALL(exit) + 5c3: b8 02 00 00 00 mov $0x2,%eax + 5c8: cd 40 int $0x40 + 5ca: c3 ret + +000005cb : +SYSCALL(wait) + 5cb: b8 03 00 00 00 mov $0x3,%eax + 5d0: cd 40 int $0x40 + 5d2: c3 ret + +000005d3 : +SYSCALL(pipe) + 5d3: b8 04 00 00 00 mov $0x4,%eax + 5d8: cd 40 int $0x40 + 5da: c3 ret + +000005db : +SYSCALL(read) + 5db: b8 05 00 00 00 mov $0x5,%eax + 5e0: cd 40 int $0x40 + 5e2: c3 ret + +000005e3 : +SYSCALL(kill) + 5e3: b8 06 00 00 00 mov $0x6,%eax + 5e8: cd 40 int $0x40 + 5ea: c3 ret + +000005eb : +SYSCALL(exec) + 5eb: b8 07 00 00 00 mov $0x7,%eax + 5f0: cd 40 int $0x40 + 5f2: c3 ret + +000005f3 : +SYSCALL(fstat) + 5f3: b8 08 00 00 00 mov $0x8,%eax + 5f8: cd 40 int $0x40 + 5fa: c3 ret + +000005fb : +SYSCALL(chdir) + 5fb: b8 09 00 00 00 mov $0x9,%eax + 600: cd 40 int $0x40 + 602: c3 ret + +00000603 : +SYSCALL(dup) + 603: b8 0a 00 00 00 mov $0xa,%eax + 608: cd 40 int $0x40 + 60a: c3 ret + +0000060b : +SYSCALL(getpid) + 60b: b8 0b 00 00 00 mov $0xb,%eax + 610: cd 40 int $0x40 + 612: c3 ret + +00000613 : +SYSCALL(sbrk) + 613: b8 0c 00 00 00 mov $0xc,%eax + 618: cd 40 int $0x40 + 61a: c3 ret + +0000061b : +SYSCALL(sleep) + 61b: b8 0d 00 00 00 mov $0xd,%eax + 620: cd 40 int $0x40 + 622: c3 ret + +00000623 : +SYSCALL(uptime) + 623: b8 0e 00 00 00 mov $0xe,%eax + 628: cd 40 int $0x40 + 62a: c3 ret + +0000062b : +SYSCALL(open) + 62b: b8 0f 00 00 00 mov $0xf,%eax + 630: cd 40 int $0x40 + 632: c3 ret + +00000633 : +SYSCALL(write) + 633: b8 10 00 00 00 mov $0x10,%eax + 638: cd 40 int $0x40 + 63a: c3 ret + +0000063b : +SYSCALL(mknod) + 63b: b8 11 00 00 00 mov $0x11,%eax + 640: cd 40 int $0x40 + 642: c3 ret + +00000643 : +SYSCALL(unlink) + 643: b8 12 00 00 00 mov $0x12,%eax + 648: cd 40 int $0x40 + 64a: c3 ret + +0000064b : +SYSCALL(link) + 64b: b8 13 00 00 00 mov $0x13,%eax + 650: cd 40 int $0x40 + 652: c3 ret + +00000653 : +SYSCALL(mkdir) + 653: b8 14 00 00 00 mov $0x14,%eax + 658: cd 40 int $0x40 + 65a: c3 ret + +0000065b : +SYSCALL(close) + 65b: b8 15 00 00 00 mov $0x15,%eax + 660: cd 40 int $0x40 + 662: c3 ret + +00000663 : +SYSCALL(getch) + 663: b8 16 00 00 00 mov $0x16,%eax + 668: cd 40 int $0x40 + 66a: c3 ret + +0000066b : +SYSCALL(greeting) + 66b: b8 17 00 00 00 mov $0x17,%eax + 670: cd 40 int $0x40 + 672: c3 ret + +00000673 : +SYSCALL(shutdown) + 673: b8 18 00 00 00 mov $0x18,%eax + 678: cd 40 int $0x40 + 67a: c3 ret + 67b: 66 90 xchg %ax,%ax + 67d: 66 90 xchg %ax,%ax + 67f: 90 nop + +00000680 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 680: 55 push %ebp + 681: 89 e5 mov %esp,%ebp + 683: 57 push %edi + 684: 56 push %esi + 685: 53 push %ebx + 686: 83 ec 3c sub $0x3c,%esp + 689: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 68c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 68e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 691: 85 d2 test %edx,%edx + 693: 0f 89 7f 00 00 00 jns 718 + 699: f6 45 08 01 testb $0x1,0x8(%ebp) + 69d: 74 79 je 718 + neg = 1; + 69f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 6a6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 6a8: 31 db xor %ebx,%ebx + 6aa: 8d 75 d7 lea -0x29(%ebp),%esi + 6ad: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 6b0: 89 c8 mov %ecx,%eax + 6b2: 31 d2 xor %edx,%edx + 6b4: 89 cf mov %ecx,%edi + 6b6: f7 75 c4 divl -0x3c(%ebp) + 6b9: 0f b6 92 f0 0a 00 00 movzbl 0xaf0(%edx),%edx + 6c0: 89 45 c0 mov %eax,-0x40(%ebp) + 6c3: 89 d8 mov %ebx,%eax + 6c5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 6c8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 6cb: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 6ce: 39 7d c4 cmp %edi,-0x3c(%ebp) + 6d1: 76 dd jbe 6b0 + if (neg) { + 6d3: 8b 4d bc mov -0x44(%ebp),%ecx + 6d6: 85 c9 test %ecx,%ecx + 6d8: 74 0c je 6e6 + buf[i++] = '-'; + 6da: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 6df: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 6e1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 6e6: 8b 7d b8 mov -0x48(%ebp),%edi + 6e9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 6ed: eb 07 jmp 6f6 + 6ef: 90 nop + putc(fd, buf[i]); + 6f0: 0f b6 13 movzbl (%ebx),%edx + 6f3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 6f6: 83 ec 04 sub $0x4,%esp + 6f9: 88 55 d7 mov %dl,-0x29(%ebp) + 6fc: 6a 01 push $0x1 + 6fe: 56 push %esi + 6ff: 57 push %edi + 700: e8 2e ff ff ff call 633 + while (--i >= 0) { + 705: 83 c4 10 add $0x10,%esp + 708: 39 de cmp %ebx,%esi + 70a: 75 e4 jne 6f0 + } +} + 70c: 8d 65 f4 lea -0xc(%ebp),%esp + 70f: 5b pop %ebx + 710: 5e pop %esi + 711: 5f pop %edi + 712: 5d pop %ebp + 713: c3 ret + 714: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 718: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 71f: eb 87 jmp 6a8 + 721: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 728: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 72f: 90 nop + +00000730 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 730: 55 push %ebp + 731: 89 e5 mov %esp,%ebp + 733: 57 push %edi + 734: 56 push %esi + 735: 53 push %ebx + 736: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 739: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 73c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 73f: 0f b6 13 movzbl (%ebx),%edx + 742: 84 d2 test %dl,%dl + 744: 74 6a je 7b0 + ap = (uint*)(void*)&fmt + 1; + 746: 8d 45 10 lea 0x10(%ebp),%eax + 749: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 74c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 74f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 751: 89 45 d0 mov %eax,-0x30(%ebp) + 754: eb 36 jmp 78c + 756: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 75d: 8d 76 00 lea 0x0(%esi),%esi + 760: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 763: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 768: 83 f8 25 cmp $0x25,%eax + 76b: 74 15 je 782 + write(fd, &c, 1); + 76d: 83 ec 04 sub $0x4,%esp + 770: 88 55 e7 mov %dl,-0x19(%ebp) + 773: 6a 01 push $0x1 + 775: 57 push %edi + 776: 56 push %esi + 777: e8 b7 fe ff ff call 633 + 77c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 77f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 782: 0f b6 13 movzbl (%ebx),%edx + 785: 83 c3 01 add $0x1,%ebx + 788: 84 d2 test %dl,%dl + 78a: 74 24 je 7b0 + c = fmt[i] & 0xff; + 78c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 78f: 85 c9 test %ecx,%ecx + 791: 74 cd je 760 + } + } + else if (state == '%') { + 793: 83 f9 25 cmp $0x25,%ecx + 796: 75 ea jne 782 + if (c == 'd') { + 798: 83 f8 25 cmp $0x25,%eax + 79b: 0f 84 07 01 00 00 je 8a8 + 7a1: 83 e8 63 sub $0x63,%eax + 7a4: 83 f8 15 cmp $0x15,%eax + 7a7: 77 17 ja 7c0 + 7a9: ff 24 85 98 0a 00 00 jmp *0xa98(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 7b0: 8d 65 f4 lea -0xc(%ebp),%esp + 7b3: 5b pop %ebx + 7b4: 5e pop %esi + 7b5: 5f pop %edi + 7b6: 5d pop %ebp + 7b7: c3 ret + 7b8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 7bf: 90 nop + write(fd, &c, 1); + 7c0: 83 ec 04 sub $0x4,%esp + 7c3: 88 55 d4 mov %dl,-0x2c(%ebp) + 7c6: 6a 01 push $0x1 + 7c8: 57 push %edi + 7c9: 56 push %esi + 7ca: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 7ce: e8 60 fe ff ff call 633 + putc(fd, c); + 7d3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 7d7: 83 c4 0c add $0xc,%esp + 7da: 88 55 e7 mov %dl,-0x19(%ebp) + 7dd: 6a 01 push $0x1 + 7df: 57 push %edi + 7e0: 56 push %esi + 7e1: e8 4d fe ff ff call 633 + putc(fd, c); + 7e6: 83 c4 10 add $0x10,%esp + state = 0; + 7e9: 31 c9 xor %ecx,%ecx + 7eb: eb 95 jmp 782 + 7ed: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 7f0: 83 ec 0c sub $0xc,%esp + 7f3: b9 10 00 00 00 mov $0x10,%ecx + 7f8: 6a 00 push $0x0 + 7fa: 8b 45 d0 mov -0x30(%ebp),%eax + 7fd: 8b 10 mov (%eax),%edx + 7ff: 89 f0 mov %esi,%eax + 801: e8 7a fe ff ff call 680 + ap++; + 806: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 80a: 83 c4 10 add $0x10,%esp + state = 0; + 80d: 31 c9 xor %ecx,%ecx + 80f: e9 6e ff ff ff jmp 782 + 814: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 818: 8b 45 d0 mov -0x30(%ebp),%eax + 81b: 8b 10 mov (%eax),%edx + ap++; + 81d: 83 c0 04 add $0x4,%eax + 820: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 823: 85 d2 test %edx,%edx + 825: 0f 84 8d 00 00 00 je 8b8 + while (*s != 0) { + 82b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 82e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 830: 84 c0 test %al,%al + 832: 0f 84 4a ff ff ff je 782 + 838: 89 5d d4 mov %ebx,-0x2c(%ebp) + 83b: 89 d3 mov %edx,%ebx + 83d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 840: 83 ec 04 sub $0x4,%esp + s++; + 843: 83 c3 01 add $0x1,%ebx + 846: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 849: 6a 01 push $0x1 + 84b: 57 push %edi + 84c: 56 push %esi + 84d: e8 e1 fd ff ff call 633 + while (*s != 0) { + 852: 0f b6 03 movzbl (%ebx),%eax + 855: 83 c4 10 add $0x10,%esp + 858: 84 c0 test %al,%al + 85a: 75 e4 jne 840 + state = 0; + 85c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 85f: 31 c9 xor %ecx,%ecx + 861: e9 1c ff ff ff jmp 782 + 866: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 86d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 870: 83 ec 0c sub $0xc,%esp + 873: b9 0a 00 00 00 mov $0xa,%ecx + 878: 6a 01 push $0x1 + 87a: e9 7b ff ff ff jmp 7fa + 87f: 90 nop + putc(fd, *ap); + 880: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 883: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 886: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 888: 6a 01 push $0x1 + 88a: 57 push %edi + 88b: 56 push %esi + putc(fd, *ap); + 88c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 88f: e8 9f fd ff ff call 633 + ap++; + 894: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 898: 83 c4 10 add $0x10,%esp + state = 0; + 89b: 31 c9 xor %ecx,%ecx + 89d: e9 e0 fe ff ff jmp 782 + 8a2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 8a8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 8ab: 83 ec 04 sub $0x4,%esp + 8ae: e9 2a ff ff ff jmp 7dd + 8b3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 8b7: 90 nop + s = "(null)"; + 8b8: ba 8e 0a 00 00 mov $0xa8e,%edx + while (*s != 0) { + 8bd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 8c0: b8 28 00 00 00 mov $0x28,%eax + 8c5: 89 d3 mov %edx,%ebx + 8c7: e9 74 ff ff ff jmp 840 + 8cc: 66 90 xchg %ax,%ax + 8ce: 66 90 xchg %ax,%ax + +000008d0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 8d0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 8d1: a1 a0 12 00 00 mov 0x12a0,%eax +void free(void *ap) { + 8d6: 89 e5 mov %esp,%ebp + 8d8: 57 push %edi + 8d9: 56 push %esi + 8da: 53 push %ebx + 8db: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 8de: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 8e1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 8e8: 89 c2 mov %eax,%edx + 8ea: 8b 00 mov (%eax),%eax + 8ec: 39 ca cmp %ecx,%edx + 8ee: 73 30 jae 920 + 8f0: 39 c1 cmp %eax,%ecx + 8f2: 72 04 jb 8f8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 8f4: 39 c2 cmp %eax,%edx + 8f6: 72 f0 jb 8e8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 8f8: 8b 73 fc mov -0x4(%ebx),%esi + 8fb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 8fe: 39 f8 cmp %edi,%eax + 900: 74 30 je 932 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 902: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 905: 8b 42 04 mov 0x4(%edx),%eax + 908: 8d 34 c2 lea (%edx,%eax,8),%esi + 90b: 39 f1 cmp %esi,%ecx + 90d: 74 3a je 949 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 90f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 911: 5b pop %ebx + freep = p; + 912: 89 15 a0 12 00 00 mov %edx,0x12a0 +} + 918: 5e pop %esi + 919: 5f pop %edi + 91a: 5d pop %ebp + 91b: c3 ret + 91c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 920: 39 c2 cmp %eax,%edx + 922: 72 c4 jb 8e8 + 924: 39 c1 cmp %eax,%ecx + 926: 73 c0 jae 8e8 + if (bp + bp->s.size == p->s.ptr) { + 928: 8b 73 fc mov -0x4(%ebx),%esi + 92b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 92e: 39 f8 cmp %edi,%eax + 930: 75 d0 jne 902 + bp->s.size += p->s.ptr->s.size; + 932: 03 70 04 add 0x4(%eax),%esi + 935: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 938: 8b 02 mov (%edx),%eax + 93a: 8b 00 mov (%eax),%eax + 93c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 93f: 8b 42 04 mov 0x4(%edx),%eax + 942: 8d 34 c2 lea (%edx,%eax,8),%esi + 945: 39 f1 cmp %esi,%ecx + 947: 75 c6 jne 90f + p->s.size += bp->s.size; + 949: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 94c: 89 15 a0 12 00 00 mov %edx,0x12a0 + p->s.size += bp->s.size; + 952: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 955: 8b 4b f8 mov -0x8(%ebx),%ecx + 958: 89 0a mov %ecx,(%edx) +} + 95a: 5b pop %ebx + 95b: 5e pop %esi + 95c: 5f pop %edi + 95d: 5d pop %ebp + 95e: c3 ret + 95f: 90 nop + +00000960 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 960: 55 push %ebp + 961: 89 e5 mov %esp,%ebp + 963: 57 push %edi + 964: 56 push %esi + 965: 53 push %ebx + 966: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 969: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 96c: 8b 3d a0 12 00 00 mov 0x12a0,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 972: 8d 70 07 lea 0x7(%eax),%esi + 975: c1 ee 03 shr $0x3,%esi + 978: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 97b: 85 ff test %edi,%edi + 97d: 0f 84 9d 00 00 00 je a20 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 983: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 985: 8b 4a 04 mov 0x4(%edx),%ecx + 988: 39 f1 cmp %esi,%ecx + 98a: 73 6a jae 9f6 + 98c: bb 00 10 00 00 mov $0x1000,%ebx + 991: 39 de cmp %ebx,%esi + 993: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 996: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 99d: 89 45 e4 mov %eax,-0x1c(%ebp) + 9a0: eb 17 jmp 9b9 + 9a2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 9a8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 9aa: 8b 48 04 mov 0x4(%eax),%ecx + 9ad: 39 f1 cmp %esi,%ecx + 9af: 73 4f jae a00 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 9b1: 8b 3d a0 12 00 00 mov 0x12a0,%edi + 9b7: 89 c2 mov %eax,%edx + 9b9: 39 d7 cmp %edx,%edi + 9bb: 75 eb jne 9a8 + p = sbrk(nu * sizeof(Header)); + 9bd: 83 ec 0c sub $0xc,%esp + 9c0: ff 75 e4 push -0x1c(%ebp) + 9c3: e8 4b fc ff ff call 613 + if (p == (char*)-1) { + 9c8: 83 c4 10 add $0x10,%esp + 9cb: 83 f8 ff cmp $0xffffffff,%eax + 9ce: 74 1c je 9ec + hp->s.size = nu; + 9d0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 9d3: 83 ec 0c sub $0xc,%esp + 9d6: 83 c0 08 add $0x8,%eax + 9d9: 50 push %eax + 9da: e8 f1 fe ff ff call 8d0 + return freep; + 9df: 8b 15 a0 12 00 00 mov 0x12a0,%edx + if ((p = morecore(nunits)) == 0) { + 9e5: 83 c4 10 add $0x10,%esp + 9e8: 85 d2 test %edx,%edx + 9ea: 75 bc jne 9a8 + return 0; + } + } + } +} + 9ec: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 9ef: 31 c0 xor %eax,%eax +} + 9f1: 5b pop %ebx + 9f2: 5e pop %esi + 9f3: 5f pop %edi + 9f4: 5d pop %ebp + 9f5: c3 ret + if (p->s.size >= nunits) { + 9f6: 89 d0 mov %edx,%eax + 9f8: 89 fa mov %edi,%edx + 9fa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + a00: 39 ce cmp %ecx,%esi + a02: 74 4c je a50 + p->s.size -= nunits; + a04: 29 f1 sub %esi,%ecx + a06: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + a09: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + a0c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + a0f: 89 15 a0 12 00 00 mov %edx,0x12a0 +} + a15: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + a18: 83 c0 08 add $0x8,%eax +} + a1b: 5b pop %ebx + a1c: 5e pop %esi + a1d: 5f pop %edi + a1e: 5d pop %ebp + a1f: c3 ret + base.s.ptr = freep = prevp = &base; + a20: c7 05 a0 12 00 00 a4 movl $0x12a4,0x12a0 + a27: 12 00 00 + base.s.size = 0; + a2a: bf a4 12 00 00 mov $0x12a4,%edi + base.s.ptr = freep = prevp = &base; + a2f: c7 05 a4 12 00 00 a4 movl $0x12a4,0x12a4 + a36: 12 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + a39: 89 fa mov %edi,%edx + base.s.size = 0; + a3b: c7 05 a8 12 00 00 00 movl $0x0,0x12a8 + a42: 00 00 00 + if (p->s.size >= nunits) { + a45: e9 42 ff ff ff jmp 98c + a4a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + a50: 8b 08 mov (%eax),%ecx + a52: 89 0a mov %ecx,(%edx) + a54: eb b9 jmp a0f diff --git a/grep.c b/grep.c new file mode 100644 index 0000000..a0aa833 --- /dev/null +++ b/grep.c @@ -0,0 +1,109 @@ +// Simple grep. Only supports ^ . * $ operators. + +#include "types.h" +#include "stat.h" +#include "user.h" + +char buf[1024]; +int match(char*, char*); + +void grep(char *pattern, int fd) { + int n, m; + char *p, *q; + + m = 0; + while ((n = read(fd, buf + m, sizeof(buf) - m - 1)) > 0) { + m += n; + buf[m] = '\0'; + p = buf; + while ((q = strchr(p, '\n')) != 0) { + *q = 0; + if (match(pattern, p)) { + *q = '\n'; + write(1, p, q + 1 - p); + } + p = q + 1; + } + if (p == buf) { + m = 0; + } + if (m > 0) { + m -= p - buf; + memmove(buf, p, m); + } + } +} + +int main(int argc, char *argv[]) { + int fd, i; + char *pattern; + + if (argc <= 1) { + printf(2, "usage: grep pattern [file ...]\n"); + exit(); + } + pattern = argv[1]; + + if (argc <= 2) { + grep(pattern, 0); + exit(); + } + + for (i = 2; i < argc; i++) { + if ((fd = open(argv[i], 0)) < 0) { + printf(1, "grep: cannot open %s\n", argv[i]); + exit(); + } + grep(pattern, fd); + close(fd); + } + exit(); +} + +// Regexp matcher from Kernighan & Pike, +// The Practice of Programming, Chapter 9. + +int matchhere(char*, char*); +int matchstar(int, char*, char*); + +int match(char *re, char *text) { + if (re[0] == '^') { + return matchhere(re + 1, text); + } + do { // must look at empty string + if (matchhere(re, text)) { + return 1; + } + } + while (*text++ != '\0'); + return 0; +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text){ + if (re[0] == '\0') { + return 1; + } + if (re[1] == '*') { + return matchstar(re[0], re + 2, text); + } + if (re[0] == '$' && re[1] == '\0') { + return *text == '\0'; + } + if (*text != '\0' && (re[0] == '.' || re[0] == *text)) { + return matchhere(re + 1, text + 1); + } + return 0; +} + +// matchstar: search for c*re at beginning of text +int matchstar(int c, char *re, char *text) { + do { // a * matches zero or more instances + if (matchhere(re, text)) { + return 1; + } + } + while (*text != '\0' && (*text++ == c || c == '.')); + return 0; +} + diff --git a/grep.d b/grep.d new file mode 100644 index 0000000..15fc65b --- /dev/null +++ b/grep.d @@ -0,0 +1 @@ +grep.o: grep.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/grep.o b/grep.o new file mode 100644 index 0000000..31f70ae Binary files /dev/null and b/grep.o differ diff --git a/grep.sym b/grep.sym new file mode 100644 index 0000000..0ff3fb4 --- /dev/null +++ b/grep.sym @@ -0,0 +1,53 @@ +00000000 grep.c +00000000 ulib.c +00000000 printf.c +00000680 printint +00000af0 digits.0 +00000000 umalloc.c +000012a0 freep +000012a4 base +00000370 strcpy +00000730 printf +0000066b greeting +00000590 memmove +000000c0 matchhere +0000063b mknod +00000490 gets +0000060b getpid +000001d0 grep +00000960 malloc +0000061b sleep +000005d3 pipe +00000663 getch +00000633 write +000005f3 fstat +000005e3 kill +000005fb chdir +000005eb exec +000005cb wait +000005db read +00000643 unlink +000005bb fork +00000613 sbrk +00000623 uptime +00000e90 __bss_start +00000430 memset +00000000 main +00000310 matchstar +000003a0 strcmp +00000673 shutdown +00000603 dup +00000ea0 buf +00000500 stat +00000e90 _edata +000012ac _end +00000170 match +0000064b link +000005c3 exit +00000550 atoi +00000400 strlen +0000062b open +00000450 strchr +00000653 mkdir +0000065b close +000008d0 free diff --git a/hello.asm b/hello.asm new file mode 100644 index 0000000..21f6e0e --- /dev/null +++ b/hello.asm @@ -0,0 +1,1129 @@ + +_hello: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 55 push %ebp + 1: 89 e5 mov %esp,%ebp + 3: 83 e4 f0 and $0xfffffff0,%esp + greeting(); + 6: e8 00 03 00 00 call 30b + exit(); + b: e8 53 02 00 00 call 263 + +00000010 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 10: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 11: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 13: 89 e5 mov %esp,%ebp + 15: 53 push %ebx + 16: 8b 4d 08 mov 0x8(%ebp),%ecx + 19: 8b 5d 0c mov 0xc(%ebp),%ebx + 1c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 20: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 24: 88 14 01 mov %dl,(%ecx,%eax,1) + 27: 83 c0 01 add $0x1,%eax + 2a: 84 d2 test %dl,%dl + 2c: 75 f2 jne 20 + ; + } + return os; +} + 2e: 8b 5d fc mov -0x4(%ebp),%ebx + 31: 89 c8 mov %ecx,%eax + 33: c9 leave + 34: c3 ret + 35: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000040 : + +int strcmp(const char *p, const char *q) { + 40: 55 push %ebp + 41: 89 e5 mov %esp,%ebp + 43: 53 push %ebx + 44: 8b 55 08 mov 0x8(%ebp),%edx + 47: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 4a: 0f b6 02 movzbl (%edx),%eax + 4d: 84 c0 test %al,%al + 4f: 75 17 jne 68 + 51: eb 3a jmp 8d + 53: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 57: 90 nop + 58: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 5c: 83 c2 01 add $0x1,%edx + 5f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 62: 84 c0 test %al,%al + 64: 74 1a je 80 + p++, q++; + 66: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 68: 0f b6 19 movzbl (%ecx),%ebx + 6b: 38 c3 cmp %al,%bl + 6d: 74 e9 je 58 + } + return (uchar) * p - (uchar) * q; + 6f: 29 d8 sub %ebx,%eax +} + 71: 8b 5d fc mov -0x4(%ebp),%ebx + 74: c9 leave + 75: c3 ret + 76: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 7d: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 80: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 84: 31 c0 xor %eax,%eax + 86: 29 d8 sub %ebx,%eax +} + 88: 8b 5d fc mov -0x4(%ebp),%ebx + 8b: c9 leave + 8c: c3 ret + return (uchar) * p - (uchar) * q; + 8d: 0f b6 19 movzbl (%ecx),%ebx + 90: 31 c0 xor %eax,%eax + 92: eb db jmp 6f + 94: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 9b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 9f: 90 nop + +000000a0 : + +uint strlen(const char *s) { + a0: 55 push %ebp + a1: 89 e5 mov %esp,%ebp + a3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + a6: 80 3a 00 cmpb $0x0,(%edx) + a9: 74 15 je c0 + ab: 31 c0 xor %eax,%eax + ad: 8d 76 00 lea 0x0(%esi),%esi + b0: 83 c0 01 add $0x1,%eax + b3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + b7: 89 c1 mov %eax,%ecx + b9: 75 f5 jne b0 + ; + } + return n; +} + bb: 89 c8 mov %ecx,%eax + bd: 5d pop %ebp + be: c3 ret + bf: 90 nop + for (n = 0; s[n]; n++) { + c0: 31 c9 xor %ecx,%ecx +} + c2: 5d pop %ebp + c3: 89 c8 mov %ecx,%eax + c5: c3 ret + c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + cd: 8d 76 00 lea 0x0(%esi),%esi + +000000d0 : + +void* memset(void *dst, int c, uint n) { + d0: 55 push %ebp + d1: 89 e5 mov %esp,%ebp + d3: 57 push %edi + d4: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + d7: 8b 4d 10 mov 0x10(%ebp),%ecx + da: 8b 45 0c mov 0xc(%ebp),%eax + dd: 89 d7 mov %edx,%edi + df: fc cld + e0: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + e2: 8b 7d fc mov -0x4(%ebp),%edi + e5: 89 d0 mov %edx,%eax + e7: c9 leave + e8: c3 ret + e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +000000f0 : + +char* strchr(const char *s, char c) { + f0: 55 push %ebp + f1: 89 e5 mov %esp,%ebp + f3: 8b 45 08 mov 0x8(%ebp),%eax + f6: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + fa: 0f b6 10 movzbl (%eax),%edx + fd: 84 d2 test %dl,%dl + ff: 75 12 jne 113 + 101: eb 1d jmp 120 + 103: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 107: 90 nop + 108: 0f b6 50 01 movzbl 0x1(%eax),%edx + 10c: 83 c0 01 add $0x1,%eax + 10f: 84 d2 test %dl,%dl + 111: 74 0d je 120 + if (*s == c) { + 113: 38 d1 cmp %dl,%cl + 115: 75 f1 jne 108 + return (char*)s; + } + } + return 0; +} + 117: 5d pop %ebp + 118: c3 ret + 119: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 120: 31 c0 xor %eax,%eax +} + 122: 5d pop %ebp + 123: c3 ret + 124: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 12b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 12f: 90 nop + +00000130 : + +char* gets(char *buf, int max) { + 130: 55 push %ebp + 131: 89 e5 mov %esp,%ebp + 133: 57 push %edi + 134: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 135: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 138: 53 push %ebx + for (i = 0; i + 1 < max;) { + 139: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 13b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 13e: eb 27 jmp 167 + cc = read(0, &c, 1); + 140: 83 ec 04 sub $0x4,%esp + 143: 6a 01 push $0x1 + 145: 57 push %edi + 146: 6a 00 push $0x0 + 148: e8 2e 01 00 00 call 27b + if (cc < 1) { + 14d: 83 c4 10 add $0x10,%esp + 150: 85 c0 test %eax,%eax + 152: 7e 1d jle 171 + break; + } + buf[i++] = c; + 154: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 158: 8b 55 08 mov 0x8(%ebp),%edx + 15b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 15f: 3c 0a cmp $0xa,%al + 161: 74 1d je 180 + 163: 3c 0d cmp $0xd,%al + 165: 74 19 je 180 + for (i = 0; i + 1 < max;) { + 167: 89 de mov %ebx,%esi + 169: 83 c3 01 add $0x1,%ebx + 16c: 3b 5d 0c cmp 0xc(%ebp),%ebx + 16f: 7c cf jl 140 + break; + } + } + buf[i] = '\0'; + 171: 8b 45 08 mov 0x8(%ebp),%eax + 174: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 178: 8d 65 f4 lea -0xc(%ebp),%esp + 17b: 5b pop %ebx + 17c: 5e pop %esi + 17d: 5f pop %edi + 17e: 5d pop %ebp + 17f: c3 ret + buf[i] = '\0'; + 180: 8b 45 08 mov 0x8(%ebp),%eax + 183: 89 de mov %ebx,%esi + 185: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 189: 8d 65 f4 lea -0xc(%ebp),%esp + 18c: 5b pop %ebx + 18d: 5e pop %esi + 18e: 5f pop %edi + 18f: 5d pop %ebp + 190: c3 ret + 191: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 198: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 19f: 90 nop + +000001a0 : + +int stat(const char *n, struct stat *st) { + 1a0: 55 push %ebp + 1a1: 89 e5 mov %esp,%ebp + 1a3: 56 push %esi + 1a4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 1a5: 83 ec 08 sub $0x8,%esp + 1a8: 6a 00 push $0x0 + 1aa: ff 75 08 push 0x8(%ebp) + 1ad: e8 19 01 00 00 call 2cb + if (fd < 0) { + 1b2: 83 c4 10 add $0x10,%esp + 1b5: 85 c0 test %eax,%eax + 1b7: 78 27 js 1e0 + return -1; + } + r = fstat(fd, st); + 1b9: 83 ec 08 sub $0x8,%esp + 1bc: ff 75 0c push 0xc(%ebp) + 1bf: 89 c3 mov %eax,%ebx + 1c1: 50 push %eax + 1c2: e8 cc 00 00 00 call 293 + close(fd); + 1c7: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 1ca: 89 c6 mov %eax,%esi + close(fd); + 1cc: e8 2a 01 00 00 call 2fb + return r; + 1d1: 83 c4 10 add $0x10,%esp +} + 1d4: 8d 65 f8 lea -0x8(%ebp),%esp + 1d7: 89 f0 mov %esi,%eax + 1d9: 5b pop %ebx + 1da: 5e pop %esi + 1db: 5d pop %ebp + 1dc: c3 ret + 1dd: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 1e0: be ff ff ff ff mov $0xffffffff,%esi + 1e5: eb ed jmp 1d4 + 1e7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ee: 66 90 xchg %ax,%ax + +000001f0 : + +int atoi(const char *s) { + 1f0: 55 push %ebp + 1f1: 89 e5 mov %esp,%ebp + 1f3: 53 push %ebx + 1f4: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 1f7: 0f be 02 movsbl (%edx),%eax + 1fa: 8d 48 d0 lea -0x30(%eax),%ecx + 1fd: 80 f9 09 cmp $0x9,%cl + n = 0; + 200: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 205: 77 1e ja 225 + 207: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 20e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 210: 83 c2 01 add $0x1,%edx + 213: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 216: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 21a: 0f be 02 movsbl (%edx),%eax + 21d: 8d 58 d0 lea -0x30(%eax),%ebx + 220: 80 fb 09 cmp $0x9,%bl + 223: 76 eb jbe 210 + } + return n; +} + 225: 8b 5d fc mov -0x4(%ebp),%ebx + 228: 89 c8 mov %ecx,%eax + 22a: c9 leave + 22b: c3 ret + 22c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000230 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 230: 55 push %ebp + 231: 89 e5 mov %esp,%ebp + 233: 57 push %edi + 234: 8b 45 10 mov 0x10(%ebp),%eax + 237: 8b 55 08 mov 0x8(%ebp),%edx + 23a: 56 push %esi + 23b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 23e: 85 c0 test %eax,%eax + 240: 7e 13 jle 255 + 242: 01 d0 add %edx,%eax + dst = vdst; + 244: 89 d7 mov %edx,%edi + 246: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 24d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 250: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 251: 39 f8 cmp %edi,%eax + 253: 75 fb jne 250 + } + return vdst; +} + 255: 5e pop %esi + 256: 89 d0 mov %edx,%eax + 258: 5f pop %edi + 259: 5d pop %ebp + 25a: c3 ret + +0000025b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 25b: b8 01 00 00 00 mov $0x1,%eax + 260: cd 40 int $0x40 + 262: c3 ret + +00000263 : +SYSCALL(exit) + 263: b8 02 00 00 00 mov $0x2,%eax + 268: cd 40 int $0x40 + 26a: c3 ret + +0000026b : +SYSCALL(wait) + 26b: b8 03 00 00 00 mov $0x3,%eax + 270: cd 40 int $0x40 + 272: c3 ret + +00000273 : +SYSCALL(pipe) + 273: b8 04 00 00 00 mov $0x4,%eax + 278: cd 40 int $0x40 + 27a: c3 ret + +0000027b : +SYSCALL(read) + 27b: b8 05 00 00 00 mov $0x5,%eax + 280: cd 40 int $0x40 + 282: c3 ret + +00000283 : +SYSCALL(kill) + 283: b8 06 00 00 00 mov $0x6,%eax + 288: cd 40 int $0x40 + 28a: c3 ret + +0000028b : +SYSCALL(exec) + 28b: b8 07 00 00 00 mov $0x7,%eax + 290: cd 40 int $0x40 + 292: c3 ret + +00000293 : +SYSCALL(fstat) + 293: b8 08 00 00 00 mov $0x8,%eax + 298: cd 40 int $0x40 + 29a: c3 ret + +0000029b : +SYSCALL(chdir) + 29b: b8 09 00 00 00 mov $0x9,%eax + 2a0: cd 40 int $0x40 + 2a2: c3 ret + +000002a3 : +SYSCALL(dup) + 2a3: b8 0a 00 00 00 mov $0xa,%eax + 2a8: cd 40 int $0x40 + 2aa: c3 ret + +000002ab : +SYSCALL(getpid) + 2ab: b8 0b 00 00 00 mov $0xb,%eax + 2b0: cd 40 int $0x40 + 2b2: c3 ret + +000002b3 : +SYSCALL(sbrk) + 2b3: b8 0c 00 00 00 mov $0xc,%eax + 2b8: cd 40 int $0x40 + 2ba: c3 ret + +000002bb : +SYSCALL(sleep) + 2bb: b8 0d 00 00 00 mov $0xd,%eax + 2c0: cd 40 int $0x40 + 2c2: c3 ret + +000002c3 : +SYSCALL(uptime) + 2c3: b8 0e 00 00 00 mov $0xe,%eax + 2c8: cd 40 int $0x40 + 2ca: c3 ret + +000002cb : +SYSCALL(open) + 2cb: b8 0f 00 00 00 mov $0xf,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(write) + 2d3: b8 10 00 00 00 mov $0x10,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(mknod) + 2db: b8 11 00 00 00 mov $0x11,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(unlink) + 2e3: b8 12 00 00 00 mov $0x12,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(link) + 2eb: b8 13 00 00 00 mov $0x13,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(mkdir) + 2f3: b8 14 00 00 00 mov $0x14,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(close) + 2fb: b8 15 00 00 00 mov $0x15,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(getch) + 303: b8 16 00 00 00 mov $0x16,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(greeting) + 30b: b8 17 00 00 00 mov $0x17,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(shutdown) + 313: b8 18 00 00 00 mov $0x18,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + 31b: 66 90 xchg %ax,%ax + 31d: 66 90 xchg %ax,%ax + 31f: 90 nop + +00000320 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 320: 55 push %ebp + 321: 89 e5 mov %esp,%ebp + 323: 57 push %edi + 324: 56 push %esi + 325: 53 push %ebx + 326: 83 ec 3c sub $0x3c,%esp + 329: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 32c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 32e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 331: 85 d2 test %edx,%edx + 333: 0f 89 7f 00 00 00 jns 3b8 + 339: f6 45 08 01 testb $0x1,0x8(%ebp) + 33d: 74 79 je 3b8 + neg = 1; + 33f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 346: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 348: 31 db xor %ebx,%ebx + 34a: 8d 75 d7 lea -0x29(%ebp),%esi + 34d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 350: 89 c8 mov %ecx,%eax + 352: 31 d2 xor %edx,%edx + 354: 89 cf mov %ecx,%edi + 356: f7 75 c4 divl -0x3c(%ebp) + 359: 0f b6 92 58 07 00 00 movzbl 0x758(%edx),%edx + 360: 89 45 c0 mov %eax,-0x40(%ebp) + 363: 89 d8 mov %ebx,%eax + 365: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 368: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 36b: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 36e: 39 7d c4 cmp %edi,-0x3c(%ebp) + 371: 76 dd jbe 350 + if (neg) { + 373: 8b 4d bc mov -0x44(%ebp),%ecx + 376: 85 c9 test %ecx,%ecx + 378: 74 0c je 386 + buf[i++] = '-'; + 37a: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 37f: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 381: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 386: 8b 7d b8 mov -0x48(%ebp),%edi + 389: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 38d: eb 07 jmp 396 + 38f: 90 nop + putc(fd, buf[i]); + 390: 0f b6 13 movzbl (%ebx),%edx + 393: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 396: 83 ec 04 sub $0x4,%esp + 399: 88 55 d7 mov %dl,-0x29(%ebp) + 39c: 6a 01 push $0x1 + 39e: 56 push %esi + 39f: 57 push %edi + 3a0: e8 2e ff ff ff call 2d3 + while (--i >= 0) { + 3a5: 83 c4 10 add $0x10,%esp + 3a8: 39 de cmp %ebx,%esi + 3aa: 75 e4 jne 390 + } +} + 3ac: 8d 65 f4 lea -0xc(%ebp),%esp + 3af: 5b pop %ebx + 3b0: 5e pop %esi + 3b1: 5f pop %edi + 3b2: 5d pop %ebp + 3b3: c3 ret + 3b4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 3b8: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 3bf: eb 87 jmp 348 + 3c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3cf: 90 nop + +000003d0 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 3d0: 55 push %ebp + 3d1: 89 e5 mov %esp,%ebp + 3d3: 57 push %edi + 3d4: 56 push %esi + 3d5: 53 push %ebx + 3d6: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 3d9: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 3dc: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 3df: 0f b6 13 movzbl (%ebx),%edx + 3e2: 84 d2 test %dl,%dl + 3e4: 74 6a je 450 + ap = (uint*)(void*)&fmt + 1; + 3e6: 8d 45 10 lea 0x10(%ebp),%eax + 3e9: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 3ec: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 3ef: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 3f1: 89 45 d0 mov %eax,-0x30(%ebp) + 3f4: eb 36 jmp 42c + 3f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3fd: 8d 76 00 lea 0x0(%esi),%esi + 400: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 403: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 408: 83 f8 25 cmp $0x25,%eax + 40b: 74 15 je 422 + write(fd, &c, 1); + 40d: 83 ec 04 sub $0x4,%esp + 410: 88 55 e7 mov %dl,-0x19(%ebp) + 413: 6a 01 push $0x1 + 415: 57 push %edi + 416: 56 push %esi + 417: e8 b7 fe ff ff call 2d3 + 41c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 41f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 422: 0f b6 13 movzbl (%ebx),%edx + 425: 83 c3 01 add $0x1,%ebx + 428: 84 d2 test %dl,%dl + 42a: 74 24 je 450 + c = fmt[i] & 0xff; + 42c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 42f: 85 c9 test %ecx,%ecx + 431: 74 cd je 400 + } + } + else if (state == '%') { + 433: 83 f9 25 cmp $0x25,%ecx + 436: 75 ea jne 422 + if (c == 'd') { + 438: 83 f8 25 cmp $0x25,%eax + 43b: 0f 84 07 01 00 00 je 548 + 441: 83 e8 63 sub $0x63,%eax + 444: 83 f8 15 cmp $0x15,%eax + 447: 77 17 ja 460 + 449: ff 24 85 00 07 00 00 jmp *0x700(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 450: 8d 65 f4 lea -0xc(%ebp),%esp + 453: 5b pop %ebx + 454: 5e pop %esi + 455: 5f pop %edi + 456: 5d pop %ebp + 457: c3 ret + 458: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 45f: 90 nop + write(fd, &c, 1); + 460: 83 ec 04 sub $0x4,%esp + 463: 88 55 d4 mov %dl,-0x2c(%ebp) + 466: 6a 01 push $0x1 + 468: 57 push %edi + 469: 56 push %esi + 46a: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 46e: e8 60 fe ff ff call 2d3 + putc(fd, c); + 473: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 477: 83 c4 0c add $0xc,%esp + 47a: 88 55 e7 mov %dl,-0x19(%ebp) + 47d: 6a 01 push $0x1 + 47f: 57 push %edi + 480: 56 push %esi + 481: e8 4d fe ff ff call 2d3 + putc(fd, c); + 486: 83 c4 10 add $0x10,%esp + state = 0; + 489: 31 c9 xor %ecx,%ecx + 48b: eb 95 jmp 422 + 48d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 490: 83 ec 0c sub $0xc,%esp + 493: b9 10 00 00 00 mov $0x10,%ecx + 498: 6a 00 push $0x0 + 49a: 8b 45 d0 mov -0x30(%ebp),%eax + 49d: 8b 10 mov (%eax),%edx + 49f: 89 f0 mov %esi,%eax + 4a1: e8 7a fe ff ff call 320 + ap++; + 4a6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 4aa: 83 c4 10 add $0x10,%esp + state = 0; + 4ad: 31 c9 xor %ecx,%ecx + 4af: e9 6e ff ff ff jmp 422 + 4b4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 4b8: 8b 45 d0 mov -0x30(%ebp),%eax + 4bb: 8b 10 mov (%eax),%edx + ap++; + 4bd: 83 c0 04 add $0x4,%eax + 4c0: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 4c3: 85 d2 test %edx,%edx + 4c5: 0f 84 8d 00 00 00 je 558 + while (*s != 0) { + 4cb: 0f b6 02 movzbl (%edx),%eax + state = 0; + 4ce: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 4d0: 84 c0 test %al,%al + 4d2: 0f 84 4a ff ff ff je 422 + 4d8: 89 5d d4 mov %ebx,-0x2c(%ebp) + 4db: 89 d3 mov %edx,%ebx + 4dd: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 4e0: 83 ec 04 sub $0x4,%esp + s++; + 4e3: 83 c3 01 add $0x1,%ebx + 4e6: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 4e9: 6a 01 push $0x1 + 4eb: 57 push %edi + 4ec: 56 push %esi + 4ed: e8 e1 fd ff ff call 2d3 + while (*s != 0) { + 4f2: 0f b6 03 movzbl (%ebx),%eax + 4f5: 83 c4 10 add $0x10,%esp + 4f8: 84 c0 test %al,%al + 4fa: 75 e4 jne 4e0 + state = 0; + 4fc: 8b 5d d4 mov -0x2c(%ebp),%ebx + 4ff: 31 c9 xor %ecx,%ecx + 501: e9 1c ff ff ff jmp 422 + 506: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 50d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 510: 83 ec 0c sub $0xc,%esp + 513: b9 0a 00 00 00 mov $0xa,%ecx + 518: 6a 01 push $0x1 + 51a: e9 7b ff ff ff jmp 49a + 51f: 90 nop + putc(fd, *ap); + 520: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 523: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 526: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 528: 6a 01 push $0x1 + 52a: 57 push %edi + 52b: 56 push %esi + putc(fd, *ap); + 52c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 52f: e8 9f fd ff ff call 2d3 + ap++; + 534: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 538: 83 c4 10 add $0x10,%esp + state = 0; + 53b: 31 c9 xor %ecx,%ecx + 53d: e9 e0 fe ff ff jmp 422 + 542: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 548: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 54b: 83 ec 04 sub $0x4,%esp + 54e: e9 2a ff ff ff jmp 47d + 553: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 557: 90 nop + s = "(null)"; + 558: ba f8 06 00 00 mov $0x6f8,%edx + while (*s != 0) { + 55d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 560: b8 28 00 00 00 mov $0x28,%eax + 565: 89 d3 mov %edx,%ebx + 567: e9 74 ff ff ff jmp 4e0 + 56c: 66 90 xchg %ax,%ax + 56e: 66 90 xchg %ax,%ax + +00000570 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 570: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 571: a1 f8 09 00 00 mov 0x9f8,%eax +void free(void *ap) { + 576: 89 e5 mov %esp,%ebp + 578: 57 push %edi + 579: 56 push %esi + 57a: 53 push %ebx + 57b: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 57e: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 581: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 588: 89 c2 mov %eax,%edx + 58a: 8b 00 mov (%eax),%eax + 58c: 39 ca cmp %ecx,%edx + 58e: 73 30 jae 5c0 + 590: 39 c1 cmp %eax,%ecx + 592: 72 04 jb 598 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 594: 39 c2 cmp %eax,%edx + 596: 72 f0 jb 588 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 598: 8b 73 fc mov -0x4(%ebx),%esi + 59b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 59e: 39 f8 cmp %edi,%eax + 5a0: 74 30 je 5d2 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 5a2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 5a5: 8b 42 04 mov 0x4(%edx),%eax + 5a8: 8d 34 c2 lea (%edx,%eax,8),%esi + 5ab: 39 f1 cmp %esi,%ecx + 5ad: 74 3a je 5e9 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 5af: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 5b1: 5b pop %ebx + freep = p; + 5b2: 89 15 f8 09 00 00 mov %edx,0x9f8 +} + 5b8: 5e pop %esi + 5b9: 5f pop %edi + 5ba: 5d pop %ebp + 5bb: c3 ret + 5bc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 5c0: 39 c2 cmp %eax,%edx + 5c2: 72 c4 jb 588 + 5c4: 39 c1 cmp %eax,%ecx + 5c6: 73 c0 jae 588 + if (bp + bp->s.size == p->s.ptr) { + 5c8: 8b 73 fc mov -0x4(%ebx),%esi + 5cb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 5ce: 39 f8 cmp %edi,%eax + 5d0: 75 d0 jne 5a2 + bp->s.size += p->s.ptr->s.size; + 5d2: 03 70 04 add 0x4(%eax),%esi + 5d5: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 5d8: 8b 02 mov (%edx),%eax + 5da: 8b 00 mov (%eax),%eax + 5dc: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 5df: 8b 42 04 mov 0x4(%edx),%eax + 5e2: 8d 34 c2 lea (%edx,%eax,8),%esi + 5e5: 39 f1 cmp %esi,%ecx + 5e7: 75 c6 jne 5af + p->s.size += bp->s.size; + 5e9: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 5ec: 89 15 f8 09 00 00 mov %edx,0x9f8 + p->s.size += bp->s.size; + 5f2: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 5f5: 8b 4b f8 mov -0x8(%ebx),%ecx + 5f8: 89 0a mov %ecx,(%edx) +} + 5fa: 5b pop %ebx + 5fb: 5e pop %esi + 5fc: 5f pop %edi + 5fd: 5d pop %ebp + 5fe: c3 ret + 5ff: 90 nop + +00000600 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 600: 55 push %ebp + 601: 89 e5 mov %esp,%ebp + 603: 57 push %edi + 604: 56 push %esi + 605: 53 push %ebx + 606: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 609: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 60c: 8b 3d f8 09 00 00 mov 0x9f8,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 612: 8d 70 07 lea 0x7(%eax),%esi + 615: c1 ee 03 shr $0x3,%esi + 618: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 61b: 85 ff test %edi,%edi + 61d: 0f 84 9d 00 00 00 je 6c0 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 623: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 625: 8b 4a 04 mov 0x4(%edx),%ecx + 628: 39 f1 cmp %esi,%ecx + 62a: 73 6a jae 696 + 62c: bb 00 10 00 00 mov $0x1000,%ebx + 631: 39 de cmp %ebx,%esi + 633: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 636: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 63d: 89 45 e4 mov %eax,-0x1c(%ebp) + 640: eb 17 jmp 659 + 642: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 648: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 64a: 8b 48 04 mov 0x4(%eax),%ecx + 64d: 39 f1 cmp %esi,%ecx + 64f: 73 4f jae 6a0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 651: 8b 3d f8 09 00 00 mov 0x9f8,%edi + 657: 89 c2 mov %eax,%edx + 659: 39 d7 cmp %edx,%edi + 65b: 75 eb jne 648 + p = sbrk(nu * sizeof(Header)); + 65d: 83 ec 0c sub $0xc,%esp + 660: ff 75 e4 push -0x1c(%ebp) + 663: e8 4b fc ff ff call 2b3 + if (p == (char*)-1) { + 668: 83 c4 10 add $0x10,%esp + 66b: 83 f8 ff cmp $0xffffffff,%eax + 66e: 74 1c je 68c + hp->s.size = nu; + 670: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 673: 83 ec 0c sub $0xc,%esp + 676: 83 c0 08 add $0x8,%eax + 679: 50 push %eax + 67a: e8 f1 fe ff ff call 570 + return freep; + 67f: 8b 15 f8 09 00 00 mov 0x9f8,%edx + if ((p = morecore(nunits)) == 0) { + 685: 83 c4 10 add $0x10,%esp + 688: 85 d2 test %edx,%edx + 68a: 75 bc jne 648 + return 0; + } + } + } +} + 68c: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 68f: 31 c0 xor %eax,%eax +} + 691: 5b pop %ebx + 692: 5e pop %esi + 693: 5f pop %edi + 694: 5d pop %ebp + 695: c3 ret + if (p->s.size >= nunits) { + 696: 89 d0 mov %edx,%eax + 698: 89 fa mov %edi,%edx + 69a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 6a0: 39 ce cmp %ecx,%esi + 6a2: 74 4c je 6f0 + p->s.size -= nunits; + 6a4: 29 f1 sub %esi,%ecx + 6a6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 6a9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 6ac: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 6af: 89 15 f8 09 00 00 mov %edx,0x9f8 +} + 6b5: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 6b8: 83 c0 08 add $0x8,%eax +} + 6bb: 5b pop %ebx + 6bc: 5e pop %esi + 6bd: 5f pop %edi + 6be: 5d pop %ebp + 6bf: c3 ret + base.s.ptr = freep = prevp = &base; + 6c0: c7 05 f8 09 00 00 fc movl $0x9fc,0x9f8 + 6c7: 09 00 00 + base.s.size = 0; + 6ca: bf fc 09 00 00 mov $0x9fc,%edi + base.s.ptr = freep = prevp = &base; + 6cf: c7 05 fc 09 00 00 fc movl $0x9fc,0x9fc + 6d6: 09 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6d9: 89 fa mov %edi,%edx + base.s.size = 0; + 6db: c7 05 00 0a 00 00 00 movl $0x0,0xa00 + 6e2: 00 00 00 + if (p->s.size >= nunits) { + 6e5: e9 42 ff ff ff jmp 62c + 6ea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 6f0: 8b 08 mov (%eax),%ecx + 6f2: 89 0a mov %ecx,(%edx) + 6f4: eb b9 jmp 6af diff --git a/hello.c b/hello.c new file mode 100644 index 0000000..e7489c6 --- /dev/null +++ b/hello.c @@ -0,0 +1,7 @@ +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + greeting(); + exit(); +} \ No newline at end of file diff --git a/hello.d b/hello.d new file mode 100644 index 0000000..8d6eb56 --- /dev/null +++ b/hello.d @@ -0,0 +1 @@ +hello.o: hello.c /usr/include/stdc-predef.h types.h user.h diff --git a/hello.o b/hello.o new file mode 100644 index 0000000..64534cf Binary files /dev/null and b/hello.o differ diff --git a/hello.sym b/hello.sym new file mode 100644 index 0000000..6d2e467 --- /dev/null +++ b/hello.sym @@ -0,0 +1,48 @@ +00000000 hello.c +00000000 ulib.c +00000000 printf.c +00000320 printint +00000758 digits.0 +00000000 umalloc.c +000009f8 freep +000009fc base +00000010 strcpy +000003d0 printf +0000030b greeting +00000230 memmove +000002db mknod +00000130 gets +000002ab getpid +00000600 malloc +000002bb sleep +00000273 pipe +00000303 getch +000002d3 write +00000293 fstat +00000283 kill +0000029b chdir +0000028b exec +0000026b wait +0000027b read +000002e3 unlink +0000025b fork +000002b3 sbrk +000002c3 uptime +000009f8 __bss_start +000000d0 memset +00000000 main +00000040 strcmp +00000313 shutdown +000002a3 dup +000001a0 stat +000009f8 _edata +00000a04 _end +000002eb link +00000263 exit +000001f0 atoi +000000a0 strlen +000002cb open +000000f0 strchr +000002f3 mkdir +000002fb close +00000570 free diff --git a/ide.c b/ide.c new file mode 100644 index 0000000..1278db5 --- /dev/null +++ b/ide.c @@ -0,0 +1,171 @@ +// Simple PIO-based (non-DMA) IDE driver code. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "x86.h" +#include "traps.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "fs.h" +#include "buf.h" + +#define SECTOR_SIZE 512 +#define IDE_BSY 0x80 +#define IDE_DRDY 0x40 +#define IDE_DF 0x20 +#define IDE_ERR 0x01 + +#define IDE_CMD_READ 0x20 +#define IDE_CMD_WRITE 0x30 +#define IDE_CMD_RDMUL 0xc4 +#define IDE_CMD_WRMUL 0xc5 + +// idequeue points to the buf now being read/written to the disk. +// idequeue->qnext points to the next buf to be processed. +// You must hold idelock while manipulating queue. + +static struct spinlock idelock; +static struct buf *idequeue; + +static int havedisk1; +static void idestart(struct buf*); + +// Wait for IDE disk to become ready. +static int idewait(int checkerr) { + int r; + + while (((r = inb(0x1f7)) & (IDE_BSY | IDE_DRDY)) != IDE_DRDY) { + ; + } + if (checkerr && (r & (IDE_DF | IDE_ERR)) != 0) { + return -1; + } + return 0; +} + +void ideinit(void) { + int i; + + initlock(&idelock, "ide"); + ioapicenable(IRQ_IDE, ncpu - 1); + idewait(0); + + // Check if disk 1 is present + outb(0x1f6, 0xe0 | (1 << 4)); + for (i = 0; i < 1000; i++) { + if (inb(0x1f7) != 0) { + havedisk1 = 1; + break; + } + } + + // Switch back to disk 0. + outb(0x1f6, 0xe0 | (0 << 4)); +} + +// Start the request for b. Caller must hold idelock. +static void idestart(struct buf *b) { + if (b == 0) { + panic("idestart"); + } + if (b->blockno >= FSSIZE) { + panic("incorrect blockno"); + } + int sector_per_block = BSIZE / SECTOR_SIZE; + int sector = b->blockno * sector_per_block; + int read_cmd = (sector_per_block == 1) ? IDE_CMD_READ : IDE_CMD_RDMUL; + int write_cmd = (sector_per_block == 1) ? IDE_CMD_WRITE : IDE_CMD_WRMUL; + + if (sector_per_block > 7) { + panic("idestart"); + } + + idewait(0); + outb(0x3f6, 0); // generate interrupt + outb(0x1f2, sector_per_block); // number of sectors + outb(0x1f3, sector & 0xff); + outb(0x1f4, (sector >> 8) & 0xff); + outb(0x1f5, (sector >> 16) & 0xff); + outb(0x1f6, 0xe0 | ((b->dev & 1) << 4) | ((sector >> 24) & 0x0f)); + if (b->flags & B_DIRTY) { + outb(0x1f7, write_cmd); + outsl(0x1f0, b->data, BSIZE / 4); + } + else { + outb(0x1f7, read_cmd); + } +} + +// Interrupt handler. +void ideintr(void) { + struct buf *b; + + // First queued buffer is the active request. + acquire(&idelock); + + if ((b = idequeue) == 0) { + release(&idelock); + return; + } + idequeue = b->qnext; + + // Read data if needed. + if (!(b->flags & B_DIRTY) && idewait(1) >= 0) { + insl(0x1f0, b->data, BSIZE / 4); + } + + // Wake process waiting for this buf. + b->flags |= B_VALID; + b->flags &= ~B_DIRTY; + wakeup(b); + + // Start disk on next buf in queue. + if (idequeue != 0) { + idestart(idequeue); + } + + release(&idelock); +} + + +// Sync buf with disk. +// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID. +// Else if B_VALID is not set, read buf from disk, set B_VALID. +void iderw(struct buf *b) { + struct buf **pp; + + if (!holdingsleep(&b->lock)) { + panic("iderw: buf not locked"); + } + if ((b->flags & (B_VALID | B_DIRTY)) == B_VALID) { + panic("iderw: nothing to do"); + } + if (b->dev != 0 && !havedisk1) { + panic("iderw: ide disk 1 not present"); + } + + acquire(&idelock); //DOC:acquire-lock + + // Append b to idequeue. + b->qnext = 0; + for (pp = &idequeue; *pp; pp = &(*pp)->qnext) { //DOC:insert-queue + ; + } + *pp = b; + + // Start disk if necessary. + if (idequeue == b) { + idestart(b); + } + + // Wait for request to finish. + while ((b->flags & (B_VALID | B_DIRTY)) != B_VALID) { + sleep(b, &idelock); + } + + release(&idelock); +} diff --git a/ide.d b/ide.d new file mode 100644 index 0000000..21155b9 --- /dev/null +++ b/ide.d @@ -0,0 +1,2 @@ +ide.o: ide.c /usr/include/stdc-predef.h types.h defs.h param.h \ + memlayout.h mmu.h proc.h x86.h traps.h spinlock.h sleeplock.h fs.h buf.h diff --git a/ide.o b/ide.o new file mode 100644 index 0000000..b8474f5 Binary files /dev/null and b/ide.o differ diff --git a/init.asm b/init.asm new file mode 100644 index 0000000..8d43f5c --- /dev/null +++ b/init.asm @@ -0,0 +1,1226 @@ + +_init: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "user.h" +#include "fcntl.h" + +char *argv[] = { "sh", 0 }; + +int main(void) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 53 push %ebx + e: 51 push %ecx + int pid, wpid; + + if (open("console", O_RDWR) < 0) { + f: 83 ec 08 sub $0x8,%esp + 12: 6a 02 push $0x2 + 14: 68 c8 07 00 00 push $0x7c8 + 19: e8 7d 03 00 00 call 39b + 1e: 83 c4 10 add $0x10,%esp + 21: 85 c0 test %eax,%eax + 23: 0f 88 8d 00 00 00 js b6 + mknod("console", 1, 1); + open("console", O_RDWR); + } + dup(0); // stdout + 29: 83 ec 0c sub $0xc,%esp + 2c: 6a 00 push $0x0 + 2e: e8 40 03 00 00 call 373 + dup(0); // stderr + 33: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 3a: e8 34 03 00 00 call 373 + 3f: 83 c4 10 add $0x10,%esp + 42: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + + for (;;) { + printf(1, "init: starting sh\n"); + 48: 83 ec 08 sub $0x8,%esp + 4b: 68 d0 07 00 00 push $0x7d0 + 50: 6a 01 push $0x1 + 52: e8 49 04 00 00 call 4a0 + pid = fork(); + 57: e8 cf 02 00 00 call 32b + if (pid < 0) { + 5c: 83 c4 10 add $0x10,%esp + pid = fork(); + 5f: 89 c3 mov %eax,%ebx + if (pid < 0) { + 61: 85 c0 test %eax,%eax + 63: 78 1a js 7f + printf(1, "init: fork failed\n"); + exit(); + } + if (pid == 0) { + 65: 74 2b je 92 + 67: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 6e: 66 90 xchg %ax,%ax + exec("sh", argv); + printf(1, "init: exec sh failed\n"); + exit(); + } + while ((wpid = wait()) >= 0 && wpid != pid) { + 70: e8 c6 02 00 00 call 33b + 75: 85 c0 test %eax,%eax + 77: 78 cf js 48 + 79: 39 c3 cmp %eax,%ebx + 7b: 75 f3 jne 70 + 7d: eb c9 jmp 48 + printf(1, "init: fork failed\n"); + 7f: 53 push %ebx + 80: 53 push %ebx + 81: 68 e3 07 00 00 push $0x7e3 + 86: 6a 01 push $0x1 + 88: e8 13 04 00 00 call 4a0 + exit(); + 8d: e8 a1 02 00 00 call 333 + exec("sh", argv); + 92: 50 push %eax + 93: 50 push %eax + 94: 68 1c 0b 00 00 push $0xb1c + 99: 68 f6 07 00 00 push $0x7f6 + 9e: e8 b8 02 00 00 call 35b + printf(1, "init: exec sh failed\n"); + a3: 5a pop %edx + a4: 59 pop %ecx + a5: 68 f9 07 00 00 push $0x7f9 + aa: 6a 01 push $0x1 + ac: e8 ef 03 00 00 call 4a0 + exit(); + b1: e8 7d 02 00 00 call 333 + mknod("console", 1, 1); + b6: 50 push %eax + b7: 6a 01 push $0x1 + b9: 6a 01 push $0x1 + bb: 68 c8 07 00 00 push $0x7c8 + c0: e8 e6 02 00 00 call 3ab + open("console", O_RDWR); + c5: 58 pop %eax + c6: 5a pop %edx + c7: 6a 02 push $0x2 + c9: 68 c8 07 00 00 push $0x7c8 + ce: e8 c8 02 00 00 call 39b + d3: 83 c4 10 add $0x10,%esp + d6: e9 4e ff ff ff jmp 29 + db: 66 90 xchg %ax,%ax + dd: 66 90 xchg %ax,%ax + df: 90 nop + +000000e0 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + e0: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + e1: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + e3: 89 e5 mov %esp,%ebp + e5: 53 push %ebx + e6: 8b 4d 08 mov 0x8(%ebp),%ecx + e9: 8b 5d 0c mov 0xc(%ebp),%ebx + ec: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + f0: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + f4: 88 14 01 mov %dl,(%ecx,%eax,1) + f7: 83 c0 01 add $0x1,%eax + fa: 84 d2 test %dl,%dl + fc: 75 f2 jne f0 + ; + } + return os; +} + fe: 8b 5d fc mov -0x4(%ebp),%ebx + 101: 89 c8 mov %ecx,%eax + 103: c9 leave + 104: c3 ret + 105: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 10c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000110 : + +int strcmp(const char *p, const char *q) { + 110: 55 push %ebp + 111: 89 e5 mov %esp,%ebp + 113: 53 push %ebx + 114: 8b 55 08 mov 0x8(%ebp),%edx + 117: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 11a: 0f b6 02 movzbl (%edx),%eax + 11d: 84 c0 test %al,%al + 11f: 75 17 jne 138 + 121: eb 3a jmp 15d + 123: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 127: 90 nop + 128: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 12c: 83 c2 01 add $0x1,%edx + 12f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 132: 84 c0 test %al,%al + 134: 74 1a je 150 + p++, q++; + 136: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 138: 0f b6 19 movzbl (%ecx),%ebx + 13b: 38 c3 cmp %al,%bl + 13d: 74 e9 je 128 + } + return (uchar) * p - (uchar) * q; + 13f: 29 d8 sub %ebx,%eax +} + 141: 8b 5d fc mov -0x4(%ebp),%ebx + 144: c9 leave + 145: c3 ret + 146: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 14d: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 150: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 154: 31 c0 xor %eax,%eax + 156: 29 d8 sub %ebx,%eax +} + 158: 8b 5d fc mov -0x4(%ebp),%ebx + 15b: c9 leave + 15c: c3 ret + return (uchar) * p - (uchar) * q; + 15d: 0f b6 19 movzbl (%ecx),%ebx + 160: 31 c0 xor %eax,%eax + 162: eb db jmp 13f + 164: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 16b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 16f: 90 nop + +00000170 : + +uint strlen(const char *s) { + 170: 55 push %ebp + 171: 89 e5 mov %esp,%ebp + 173: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 176: 80 3a 00 cmpb $0x0,(%edx) + 179: 74 15 je 190 + 17b: 31 c0 xor %eax,%eax + 17d: 8d 76 00 lea 0x0(%esi),%esi + 180: 83 c0 01 add $0x1,%eax + 183: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 187: 89 c1 mov %eax,%ecx + 189: 75 f5 jne 180 + ; + } + return n; +} + 18b: 89 c8 mov %ecx,%eax + 18d: 5d pop %ebp + 18e: c3 ret + 18f: 90 nop + for (n = 0; s[n]; n++) { + 190: 31 c9 xor %ecx,%ecx +} + 192: 5d pop %ebp + 193: 89 c8 mov %ecx,%eax + 195: c3 ret + 196: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 19d: 8d 76 00 lea 0x0(%esi),%esi + +000001a0 : + +void* memset(void *dst, int c, uint n) { + 1a0: 55 push %ebp + 1a1: 89 e5 mov %esp,%ebp + 1a3: 57 push %edi + 1a4: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 1a7: 8b 4d 10 mov 0x10(%ebp),%ecx + 1aa: 8b 45 0c mov 0xc(%ebp),%eax + 1ad: 89 d7 mov %edx,%edi + 1af: fc cld + 1b0: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 1b2: 8b 7d fc mov -0x4(%ebp),%edi + 1b5: 89 d0 mov %edx,%eax + 1b7: c9 leave + 1b8: c3 ret + 1b9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +000001c0 : + +char* strchr(const char *s, char c) { + 1c0: 55 push %ebp + 1c1: 89 e5 mov %esp,%ebp + 1c3: 8b 45 08 mov 0x8(%ebp),%eax + 1c6: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 1ca: 0f b6 10 movzbl (%eax),%edx + 1cd: 84 d2 test %dl,%dl + 1cf: 75 12 jne 1e3 + 1d1: eb 1d jmp 1f0 + 1d3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1d7: 90 nop + 1d8: 0f b6 50 01 movzbl 0x1(%eax),%edx + 1dc: 83 c0 01 add $0x1,%eax + 1df: 84 d2 test %dl,%dl + 1e1: 74 0d je 1f0 + if (*s == c) { + 1e3: 38 d1 cmp %dl,%cl + 1e5: 75 f1 jne 1d8 + return (char*)s; + } + } + return 0; +} + 1e7: 5d pop %ebp + 1e8: c3 ret + 1e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 1f0: 31 c0 xor %eax,%eax +} + 1f2: 5d pop %ebp + 1f3: c3 ret + 1f4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1fb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1ff: 90 nop + +00000200 : + +char* gets(char *buf, int max) { + 200: 55 push %ebp + 201: 89 e5 mov %esp,%ebp + 203: 57 push %edi + 204: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 205: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 208: 53 push %ebx + for (i = 0; i + 1 < max;) { + 209: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 20b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 20e: eb 27 jmp 237 + cc = read(0, &c, 1); + 210: 83 ec 04 sub $0x4,%esp + 213: 6a 01 push $0x1 + 215: 57 push %edi + 216: 6a 00 push $0x0 + 218: e8 2e 01 00 00 call 34b + if (cc < 1) { + 21d: 83 c4 10 add $0x10,%esp + 220: 85 c0 test %eax,%eax + 222: 7e 1d jle 241 + break; + } + buf[i++] = c; + 224: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 228: 8b 55 08 mov 0x8(%ebp),%edx + 22b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 22f: 3c 0a cmp $0xa,%al + 231: 74 1d je 250 + 233: 3c 0d cmp $0xd,%al + 235: 74 19 je 250 + for (i = 0; i + 1 < max;) { + 237: 89 de mov %ebx,%esi + 239: 83 c3 01 add $0x1,%ebx + 23c: 3b 5d 0c cmp 0xc(%ebp),%ebx + 23f: 7c cf jl 210 + break; + } + } + buf[i] = '\0'; + 241: 8b 45 08 mov 0x8(%ebp),%eax + 244: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 248: 8d 65 f4 lea -0xc(%ebp),%esp + 24b: 5b pop %ebx + 24c: 5e pop %esi + 24d: 5f pop %edi + 24e: 5d pop %ebp + 24f: c3 ret + buf[i] = '\0'; + 250: 8b 45 08 mov 0x8(%ebp),%eax + 253: 89 de mov %ebx,%esi + 255: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 259: 8d 65 f4 lea -0xc(%ebp),%esp + 25c: 5b pop %ebx + 25d: 5e pop %esi + 25e: 5f pop %edi + 25f: 5d pop %ebp + 260: c3 ret + 261: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 268: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 26f: 90 nop + +00000270 : + +int stat(const char *n, struct stat *st) { + 270: 55 push %ebp + 271: 89 e5 mov %esp,%ebp + 273: 56 push %esi + 274: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 275: 83 ec 08 sub $0x8,%esp + 278: 6a 00 push $0x0 + 27a: ff 75 08 push 0x8(%ebp) + 27d: e8 19 01 00 00 call 39b + if (fd < 0) { + 282: 83 c4 10 add $0x10,%esp + 285: 85 c0 test %eax,%eax + 287: 78 27 js 2b0 + return -1; + } + r = fstat(fd, st); + 289: 83 ec 08 sub $0x8,%esp + 28c: ff 75 0c push 0xc(%ebp) + 28f: 89 c3 mov %eax,%ebx + 291: 50 push %eax + 292: e8 cc 00 00 00 call 363 + close(fd); + 297: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 29a: 89 c6 mov %eax,%esi + close(fd); + 29c: e8 2a 01 00 00 call 3cb + return r; + 2a1: 83 c4 10 add $0x10,%esp +} + 2a4: 8d 65 f8 lea -0x8(%ebp),%esp + 2a7: 89 f0 mov %esi,%eax + 2a9: 5b pop %ebx + 2aa: 5e pop %esi + 2ab: 5d pop %ebp + 2ac: c3 ret + 2ad: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 2b0: be ff ff ff ff mov $0xffffffff,%esi + 2b5: eb ed jmp 2a4 + 2b7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2be: 66 90 xchg %ax,%ax + +000002c0 : + +int atoi(const char *s) { + 2c0: 55 push %ebp + 2c1: 89 e5 mov %esp,%ebp + 2c3: 53 push %ebx + 2c4: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 2c7: 0f be 02 movsbl (%edx),%eax + 2ca: 8d 48 d0 lea -0x30(%eax),%ecx + 2cd: 80 f9 09 cmp $0x9,%cl + n = 0; + 2d0: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 2d5: 77 1e ja 2f5 + 2d7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2de: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 2e0: 83 c2 01 add $0x1,%edx + 2e3: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 2e6: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 2ea: 0f be 02 movsbl (%edx),%eax + 2ed: 8d 58 d0 lea -0x30(%eax),%ebx + 2f0: 80 fb 09 cmp $0x9,%bl + 2f3: 76 eb jbe 2e0 + } + return n; +} + 2f5: 8b 5d fc mov -0x4(%ebp),%ebx + 2f8: 89 c8 mov %ecx,%eax + 2fa: c9 leave + 2fb: c3 ret + 2fc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000300 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 300: 55 push %ebp + 301: 89 e5 mov %esp,%ebp + 303: 57 push %edi + 304: 8b 45 10 mov 0x10(%ebp),%eax + 307: 8b 55 08 mov 0x8(%ebp),%edx + 30a: 56 push %esi + 30b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 30e: 85 c0 test %eax,%eax + 310: 7e 13 jle 325 + 312: 01 d0 add %edx,%eax + dst = vdst; + 314: 89 d7 mov %edx,%edi + 316: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 31d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 320: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 321: 39 f8 cmp %edi,%eax + 323: 75 fb jne 320 + } + return vdst; +} + 325: 5e pop %esi + 326: 89 d0 mov %edx,%eax + 328: 5f pop %edi + 329: 5d pop %ebp + 32a: c3 ret + +0000032b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 32b: b8 01 00 00 00 mov $0x1,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(exit) + 333: b8 02 00 00 00 mov $0x2,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(wait) + 33b: b8 03 00 00 00 mov $0x3,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(pipe) + 343: b8 04 00 00 00 mov $0x4,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(read) + 34b: b8 05 00 00 00 mov $0x5,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(kill) + 353: b8 06 00 00 00 mov $0x6,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(exec) + 35b: b8 07 00 00 00 mov $0x7,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(fstat) + 363: b8 08 00 00 00 mov $0x8,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + +0000036b : +SYSCALL(chdir) + 36b: b8 09 00 00 00 mov $0x9,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(dup) + 373: b8 0a 00 00 00 mov $0xa,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + +0000037b : +SYSCALL(getpid) + 37b: b8 0b 00 00 00 mov $0xb,%eax + 380: cd 40 int $0x40 + 382: c3 ret + +00000383 : +SYSCALL(sbrk) + 383: b8 0c 00 00 00 mov $0xc,%eax + 388: cd 40 int $0x40 + 38a: c3 ret + +0000038b : +SYSCALL(sleep) + 38b: b8 0d 00 00 00 mov $0xd,%eax + 390: cd 40 int $0x40 + 392: c3 ret + +00000393 : +SYSCALL(uptime) + 393: b8 0e 00 00 00 mov $0xe,%eax + 398: cd 40 int $0x40 + 39a: c3 ret + +0000039b : +SYSCALL(open) + 39b: b8 0f 00 00 00 mov $0xf,%eax + 3a0: cd 40 int $0x40 + 3a2: c3 ret + +000003a3 : +SYSCALL(write) + 3a3: b8 10 00 00 00 mov $0x10,%eax + 3a8: cd 40 int $0x40 + 3aa: c3 ret + +000003ab : +SYSCALL(mknod) + 3ab: b8 11 00 00 00 mov $0x11,%eax + 3b0: cd 40 int $0x40 + 3b2: c3 ret + +000003b3 : +SYSCALL(unlink) + 3b3: b8 12 00 00 00 mov $0x12,%eax + 3b8: cd 40 int $0x40 + 3ba: c3 ret + +000003bb : +SYSCALL(link) + 3bb: b8 13 00 00 00 mov $0x13,%eax + 3c0: cd 40 int $0x40 + 3c2: c3 ret + +000003c3 : +SYSCALL(mkdir) + 3c3: b8 14 00 00 00 mov $0x14,%eax + 3c8: cd 40 int $0x40 + 3ca: c3 ret + +000003cb : +SYSCALL(close) + 3cb: b8 15 00 00 00 mov $0x15,%eax + 3d0: cd 40 int $0x40 + 3d2: c3 ret + +000003d3 : +SYSCALL(getch) + 3d3: b8 16 00 00 00 mov $0x16,%eax + 3d8: cd 40 int $0x40 + 3da: c3 ret + +000003db : +SYSCALL(greeting) + 3db: b8 17 00 00 00 mov $0x17,%eax + 3e0: cd 40 int $0x40 + 3e2: c3 ret + +000003e3 : +SYSCALL(shutdown) + 3e3: b8 18 00 00 00 mov $0x18,%eax + 3e8: cd 40 int $0x40 + 3ea: c3 ret + 3eb: 66 90 xchg %ax,%ax + 3ed: 66 90 xchg %ax,%ax + 3ef: 90 nop + +000003f0 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 3f0: 55 push %ebp + 3f1: 89 e5 mov %esp,%ebp + 3f3: 57 push %edi + 3f4: 56 push %esi + 3f5: 53 push %ebx + 3f6: 83 ec 3c sub $0x3c,%esp + 3f9: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 3fc: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 3fe: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 401: 85 d2 test %edx,%edx + 403: 0f 89 7f 00 00 00 jns 488 + 409: f6 45 08 01 testb $0x1,0x8(%ebp) + 40d: 74 79 je 488 + neg = 1; + 40f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 416: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 418: 31 db xor %ebx,%ebx + 41a: 8d 75 d7 lea -0x29(%ebp),%esi + 41d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 420: 89 c8 mov %ecx,%eax + 422: 31 d2 xor %edx,%edx + 424: 89 cf mov %ecx,%edi + 426: f7 75 c4 divl -0x3c(%ebp) + 429: 0f b6 92 70 08 00 00 movzbl 0x870(%edx),%edx + 430: 89 45 c0 mov %eax,-0x40(%ebp) + 433: 89 d8 mov %ebx,%eax + 435: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 438: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 43b: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 43e: 39 7d c4 cmp %edi,-0x3c(%ebp) + 441: 76 dd jbe 420 + if (neg) { + 443: 8b 4d bc mov -0x44(%ebp),%ecx + 446: 85 c9 test %ecx,%ecx + 448: 74 0c je 456 + buf[i++] = '-'; + 44a: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 44f: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 451: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 456: 8b 7d b8 mov -0x48(%ebp),%edi + 459: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 45d: eb 07 jmp 466 + 45f: 90 nop + putc(fd, buf[i]); + 460: 0f b6 13 movzbl (%ebx),%edx + 463: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 466: 83 ec 04 sub $0x4,%esp + 469: 88 55 d7 mov %dl,-0x29(%ebp) + 46c: 6a 01 push $0x1 + 46e: 56 push %esi + 46f: 57 push %edi + 470: e8 2e ff ff ff call 3a3 + while (--i >= 0) { + 475: 83 c4 10 add $0x10,%esp + 478: 39 de cmp %ebx,%esi + 47a: 75 e4 jne 460 + } +} + 47c: 8d 65 f4 lea -0xc(%ebp),%esp + 47f: 5b pop %ebx + 480: 5e pop %esi + 481: 5f pop %edi + 482: 5d pop %ebp + 483: c3 ret + 484: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 488: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 48f: eb 87 jmp 418 + 491: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 498: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 49f: 90 nop + +000004a0 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 4a0: 55 push %ebp + 4a1: 89 e5 mov %esp,%ebp + 4a3: 57 push %edi + 4a4: 56 push %esi + 4a5: 53 push %ebx + 4a6: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 4a9: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 4ac: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 4af: 0f b6 13 movzbl (%ebx),%edx + 4b2: 84 d2 test %dl,%dl + 4b4: 74 6a je 520 + ap = (uint*)(void*)&fmt + 1; + 4b6: 8d 45 10 lea 0x10(%ebp),%eax + 4b9: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 4bc: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 4bf: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 4c1: 89 45 d0 mov %eax,-0x30(%ebp) + 4c4: eb 36 jmp 4fc + 4c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4cd: 8d 76 00 lea 0x0(%esi),%esi + 4d0: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 4d3: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 4d8: 83 f8 25 cmp $0x25,%eax + 4db: 74 15 je 4f2 + write(fd, &c, 1); + 4dd: 83 ec 04 sub $0x4,%esp + 4e0: 88 55 e7 mov %dl,-0x19(%ebp) + 4e3: 6a 01 push $0x1 + 4e5: 57 push %edi + 4e6: 56 push %esi + 4e7: e8 b7 fe ff ff call 3a3 + 4ec: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 4ef: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 4f2: 0f b6 13 movzbl (%ebx),%edx + 4f5: 83 c3 01 add $0x1,%ebx + 4f8: 84 d2 test %dl,%dl + 4fa: 74 24 je 520 + c = fmt[i] & 0xff; + 4fc: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 4ff: 85 c9 test %ecx,%ecx + 501: 74 cd je 4d0 + } + } + else if (state == '%') { + 503: 83 f9 25 cmp $0x25,%ecx + 506: 75 ea jne 4f2 + if (c == 'd') { + 508: 83 f8 25 cmp $0x25,%eax + 50b: 0f 84 07 01 00 00 je 618 + 511: 83 e8 63 sub $0x63,%eax + 514: 83 f8 15 cmp $0x15,%eax + 517: 77 17 ja 530 + 519: ff 24 85 18 08 00 00 jmp *0x818(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 520: 8d 65 f4 lea -0xc(%ebp),%esp + 523: 5b pop %ebx + 524: 5e pop %esi + 525: 5f pop %edi + 526: 5d pop %ebp + 527: c3 ret + 528: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 52f: 90 nop + write(fd, &c, 1); + 530: 83 ec 04 sub $0x4,%esp + 533: 88 55 d4 mov %dl,-0x2c(%ebp) + 536: 6a 01 push $0x1 + 538: 57 push %edi + 539: 56 push %esi + 53a: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 53e: e8 60 fe ff ff call 3a3 + putc(fd, c); + 543: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 547: 83 c4 0c add $0xc,%esp + 54a: 88 55 e7 mov %dl,-0x19(%ebp) + 54d: 6a 01 push $0x1 + 54f: 57 push %edi + 550: 56 push %esi + 551: e8 4d fe ff ff call 3a3 + putc(fd, c); + 556: 83 c4 10 add $0x10,%esp + state = 0; + 559: 31 c9 xor %ecx,%ecx + 55b: eb 95 jmp 4f2 + 55d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 560: 83 ec 0c sub $0xc,%esp + 563: b9 10 00 00 00 mov $0x10,%ecx + 568: 6a 00 push $0x0 + 56a: 8b 45 d0 mov -0x30(%ebp),%eax + 56d: 8b 10 mov (%eax),%edx + 56f: 89 f0 mov %esi,%eax + 571: e8 7a fe ff ff call 3f0 + ap++; + 576: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 57a: 83 c4 10 add $0x10,%esp + state = 0; + 57d: 31 c9 xor %ecx,%ecx + 57f: e9 6e ff ff ff jmp 4f2 + 584: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 588: 8b 45 d0 mov -0x30(%ebp),%eax + 58b: 8b 10 mov (%eax),%edx + ap++; + 58d: 83 c0 04 add $0x4,%eax + 590: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 593: 85 d2 test %edx,%edx + 595: 0f 84 8d 00 00 00 je 628 + while (*s != 0) { + 59b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 59e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 5a0: 84 c0 test %al,%al + 5a2: 0f 84 4a ff ff ff je 4f2 + 5a8: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5ab: 89 d3 mov %edx,%ebx + 5ad: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 5b0: 83 ec 04 sub $0x4,%esp + s++; + 5b3: 83 c3 01 add $0x1,%ebx + 5b6: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 5b9: 6a 01 push $0x1 + 5bb: 57 push %edi + 5bc: 56 push %esi + 5bd: e8 e1 fd ff ff call 3a3 + while (*s != 0) { + 5c2: 0f b6 03 movzbl (%ebx),%eax + 5c5: 83 c4 10 add $0x10,%esp + 5c8: 84 c0 test %al,%al + 5ca: 75 e4 jne 5b0 + state = 0; + 5cc: 8b 5d d4 mov -0x2c(%ebp),%ebx + 5cf: 31 c9 xor %ecx,%ecx + 5d1: e9 1c ff ff ff jmp 4f2 + 5d6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5dd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 5e0: 83 ec 0c sub $0xc,%esp + 5e3: b9 0a 00 00 00 mov $0xa,%ecx + 5e8: 6a 01 push $0x1 + 5ea: e9 7b ff ff ff jmp 56a + 5ef: 90 nop + putc(fd, *ap); + 5f0: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 5f3: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 5f6: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 5f8: 6a 01 push $0x1 + 5fa: 57 push %edi + 5fb: 56 push %esi + putc(fd, *ap); + 5fc: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 5ff: e8 9f fd ff ff call 3a3 + ap++; + 604: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 608: 83 c4 10 add $0x10,%esp + state = 0; + 60b: 31 c9 xor %ecx,%ecx + 60d: e9 e0 fe ff ff jmp 4f2 + 612: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 618: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 61b: 83 ec 04 sub $0x4,%esp + 61e: e9 2a ff ff ff jmp 54d + 623: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 627: 90 nop + s = "(null)"; + 628: ba 0f 08 00 00 mov $0x80f,%edx + while (*s != 0) { + 62d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 630: b8 28 00 00 00 mov $0x28,%eax + 635: 89 d3 mov %edx,%ebx + 637: e9 74 ff ff ff jmp 5b0 + 63c: 66 90 xchg %ax,%ax + 63e: 66 90 xchg %ax,%ax + +00000640 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 640: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 641: a1 24 0b 00 00 mov 0xb24,%eax +void free(void *ap) { + 646: 89 e5 mov %esp,%ebp + 648: 57 push %edi + 649: 56 push %esi + 64a: 53 push %ebx + 64b: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 64e: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 651: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 658: 89 c2 mov %eax,%edx + 65a: 8b 00 mov (%eax),%eax + 65c: 39 ca cmp %ecx,%edx + 65e: 73 30 jae 690 + 660: 39 c1 cmp %eax,%ecx + 662: 72 04 jb 668 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 664: 39 c2 cmp %eax,%edx + 666: 72 f0 jb 658 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 668: 8b 73 fc mov -0x4(%ebx),%esi + 66b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 66e: 39 f8 cmp %edi,%eax + 670: 74 30 je 6a2 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 672: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 675: 8b 42 04 mov 0x4(%edx),%eax + 678: 8d 34 c2 lea (%edx,%eax,8),%esi + 67b: 39 f1 cmp %esi,%ecx + 67d: 74 3a je 6b9 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 67f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 681: 5b pop %ebx + freep = p; + 682: 89 15 24 0b 00 00 mov %edx,0xb24 +} + 688: 5e pop %esi + 689: 5f pop %edi + 68a: 5d pop %ebp + 68b: c3 ret + 68c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 690: 39 c2 cmp %eax,%edx + 692: 72 c4 jb 658 + 694: 39 c1 cmp %eax,%ecx + 696: 73 c0 jae 658 + if (bp + bp->s.size == p->s.ptr) { + 698: 8b 73 fc mov -0x4(%ebx),%esi + 69b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 69e: 39 f8 cmp %edi,%eax + 6a0: 75 d0 jne 672 + bp->s.size += p->s.ptr->s.size; + 6a2: 03 70 04 add 0x4(%eax),%esi + 6a5: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 6a8: 8b 02 mov (%edx),%eax + 6aa: 8b 00 mov (%eax),%eax + 6ac: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 6af: 8b 42 04 mov 0x4(%edx),%eax + 6b2: 8d 34 c2 lea (%edx,%eax,8),%esi + 6b5: 39 f1 cmp %esi,%ecx + 6b7: 75 c6 jne 67f + p->s.size += bp->s.size; + 6b9: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 6bc: 89 15 24 0b 00 00 mov %edx,0xb24 + p->s.size += bp->s.size; + 6c2: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 6c5: 8b 4b f8 mov -0x8(%ebx),%ecx + 6c8: 89 0a mov %ecx,(%edx) +} + 6ca: 5b pop %ebx + 6cb: 5e pop %esi + 6cc: 5f pop %edi + 6cd: 5d pop %ebp + 6ce: c3 ret + 6cf: 90 nop + +000006d0 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 6d0: 55 push %ebp + 6d1: 89 e5 mov %esp,%ebp + 6d3: 57 push %edi + 6d4: 56 push %esi + 6d5: 53 push %ebx + 6d6: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 6d9: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 6dc: 8b 3d 24 0b 00 00 mov 0xb24,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 6e2: 8d 70 07 lea 0x7(%eax),%esi + 6e5: c1 ee 03 shr $0x3,%esi + 6e8: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 6eb: 85 ff test %edi,%edi + 6ed: 0f 84 9d 00 00 00 je 790 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6f3: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 6f5: 8b 4a 04 mov 0x4(%edx),%ecx + 6f8: 39 f1 cmp %esi,%ecx + 6fa: 73 6a jae 766 + 6fc: bb 00 10 00 00 mov $0x1000,%ebx + 701: 39 de cmp %ebx,%esi + 703: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 706: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 70d: 89 45 e4 mov %eax,-0x1c(%ebp) + 710: eb 17 jmp 729 + 712: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 718: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 71a: 8b 48 04 mov 0x4(%eax),%ecx + 71d: 39 f1 cmp %esi,%ecx + 71f: 73 4f jae 770 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 721: 8b 3d 24 0b 00 00 mov 0xb24,%edi + 727: 89 c2 mov %eax,%edx + 729: 39 d7 cmp %edx,%edi + 72b: 75 eb jne 718 + p = sbrk(nu * sizeof(Header)); + 72d: 83 ec 0c sub $0xc,%esp + 730: ff 75 e4 push -0x1c(%ebp) + 733: e8 4b fc ff ff call 383 + if (p == (char*)-1) { + 738: 83 c4 10 add $0x10,%esp + 73b: 83 f8 ff cmp $0xffffffff,%eax + 73e: 74 1c je 75c + hp->s.size = nu; + 740: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 743: 83 ec 0c sub $0xc,%esp + 746: 83 c0 08 add $0x8,%eax + 749: 50 push %eax + 74a: e8 f1 fe ff ff call 640 + return freep; + 74f: 8b 15 24 0b 00 00 mov 0xb24,%edx + if ((p = morecore(nunits)) == 0) { + 755: 83 c4 10 add $0x10,%esp + 758: 85 d2 test %edx,%edx + 75a: 75 bc jne 718 + return 0; + } + } + } +} + 75c: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 75f: 31 c0 xor %eax,%eax +} + 761: 5b pop %ebx + 762: 5e pop %esi + 763: 5f pop %edi + 764: 5d pop %ebp + 765: c3 ret + if (p->s.size >= nunits) { + 766: 89 d0 mov %edx,%eax + 768: 89 fa mov %edi,%edx + 76a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 770: 39 ce cmp %ecx,%esi + 772: 74 4c je 7c0 + p->s.size -= nunits; + 774: 29 f1 sub %esi,%ecx + 776: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 779: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 77c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 77f: 89 15 24 0b 00 00 mov %edx,0xb24 +} + 785: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 788: 83 c0 08 add $0x8,%eax +} + 78b: 5b pop %ebx + 78c: 5e pop %esi + 78d: 5f pop %edi + 78e: 5d pop %ebp + 78f: c3 ret + base.s.ptr = freep = prevp = &base; + 790: c7 05 24 0b 00 00 28 movl $0xb28,0xb24 + 797: 0b 00 00 + base.s.size = 0; + 79a: bf 28 0b 00 00 mov $0xb28,%edi + base.s.ptr = freep = prevp = &base; + 79f: c7 05 28 0b 00 00 28 movl $0xb28,0xb28 + 7a6: 0b 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 7a9: 89 fa mov %edi,%edx + base.s.size = 0; + 7ab: c7 05 2c 0b 00 00 00 movl $0x0,0xb2c + 7b2: 00 00 00 + if (p->s.size >= nunits) { + 7b5: e9 42 ff ff ff jmp 6fc + 7ba: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 7c0: 8b 08 mov (%eax),%ecx + 7c2: 89 0a mov %ecx,(%edx) + 7c4: eb b9 jmp 77f diff --git a/init.c b/init.c new file mode 100644 index 0000000..b236262 --- /dev/null +++ b/init.c @@ -0,0 +1,35 @@ +// init: The initial user-level program + +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fcntl.h" + +char *argv[] = { "sh", 0 }; + +int main(void) { + int pid, wpid; + + if (open("console", O_RDWR) < 0) { + mknod("console", 1, 1); + open("console", O_RDWR); + } + dup(0); // stdout + dup(0); // stderr + + for (;;) { + printf(1, "init: starting sh\n"); + pid = fork(); + if (pid < 0) { + printf(1, "init: fork failed\n"); + exit(); + } + if (pid == 0) { + exec("sh", argv); + printf(1, "init: exec sh failed\n"); + exit(); + } + while ((wpid = wait()) >= 0 && wpid != pid) { + } + } +} diff --git a/init.d b/init.d new file mode 100644 index 0000000..ee304c8 --- /dev/null +++ b/init.d @@ -0,0 +1 @@ +init.o: init.c /usr/include/stdc-predef.h types.h stat.h user.h fcntl.h diff --git a/init.o b/init.o new file mode 100644 index 0000000..5f7bf3d Binary files /dev/null and b/init.o differ diff --git a/init.sym b/init.sym new file mode 100644 index 0000000..2617668 --- /dev/null +++ b/init.sym @@ -0,0 +1,49 @@ +00000000 init.c +00000000 ulib.c +00000000 printf.c +000003f0 printint +00000870 digits.0 +00000000 umalloc.c +00000b24 freep +00000b28 base +000000e0 strcpy +000004a0 printf +000003db greeting +00000b1c argv +00000300 memmove +000003ab mknod +00000200 gets +0000037b getpid +000006d0 malloc +0000038b sleep +00000343 pipe +000003d3 getch +000003a3 write +00000363 fstat +00000353 kill +0000036b chdir +0000035b exec +0000033b wait +0000034b read +000003b3 unlink +0000032b fork +00000383 sbrk +00000393 uptime +00000b24 __bss_start +000001a0 memset +00000000 main +00000110 strcmp +000003e3 shutdown +00000373 dup +00000270 stat +00000b24 _edata +00000b30 _end +000003bb link +00000333 exit +000002c0 atoi +00000170 strlen +0000039b open +000001c0 strchr +000003c3 mkdir +000003cb close +00000640 free diff --git a/initcode b/initcode new file mode 100644 index 0000000..773d26c Binary files /dev/null and b/initcode differ diff --git a/initcode.S b/initcode.S new file mode 100644 index 0000000..71842d8 --- /dev/null +++ b/initcode.S @@ -0,0 +1,32 @@ +# Initial process execs /init. +# This code runs in user space. + +#include "syscall.h" +#include "traps.h" + + +# exec(init, argv) +.globl start +start: + pushl $argv + pushl $init + pushl $0 // where caller pc would be + movl $SYS_exec, %eax + int $T_SYSCALL + +# for(;;) exit(); +exit: + movl $SYS_exit, %eax + int $T_SYSCALL + jmp exit + +# char init[] = "/init\0"; +init: + .string "/init\0" + +# char *argv[] = { init, 0 }; + .p2align 2 +argv: + .long init + .long 0 + diff --git a/initcode.asm b/initcode.asm new file mode 100644 index 0000000..030ab5b --- /dev/null +++ b/initcode.asm @@ -0,0 +1,43 @@ + +initcode.o: file format elf32-i386 + + +Disassembly of section .text: + +00000000 : + + +# exec(init, argv) +.globl start +start: + pushl $argv + 0: 68 24 00 00 00 push $0x24 + pushl $init + 5: 68 1c 00 00 00 push $0x1c + pushl $0 // where caller pc would be + a: 6a 00 push $0x0 + movl $SYS_exec, %eax + c: b8 07 00 00 00 mov $0x7,%eax + int $T_SYSCALL + 11: cd 40 int $0x40 + +00000013 : + +# for(;;) exit(); +exit: + movl $SYS_exit, %eax + 13: b8 02 00 00 00 mov $0x2,%eax + int $T_SYSCALL + 18: cd 40 int $0x40 + jmp exit + 1a: eb f7 jmp 13 + +0000001c : + 1c: 2f das + 1d: 69 6e 69 74 00 00 90 imul $0x90000074,0x69(%esi),%ebp + +00000024 : + 24: 1c 00 sbb $0x0,%al + 26: 00 00 add %al,(%eax) + 28: 00 00 add %al,(%eax) + ... diff --git a/initcode.d b/initcode.d new file mode 100644 index 0000000..ab1af4d --- /dev/null +++ b/initcode.d @@ -0,0 +1 @@ +initcode.o: initcode.S syscall.h traps.h diff --git a/initcode.o b/initcode.o new file mode 100644 index 0000000..0e6fa21 Binary files /dev/null and b/initcode.o differ diff --git a/initcode.out b/initcode.out new file mode 100644 index 0000000..ee27f9d Binary files /dev/null and b/initcode.out differ diff --git a/ioapic.c b/ioapic.c new file mode 100644 index 0000000..1756da4 --- /dev/null +++ b/ioapic.c @@ -0,0 +1,68 @@ +// The I/O APIC manages hardware interrupts for an SMP system. +// http://www.intel.com/design/chipsets/datashts/29056601.pdf +// See also picirq.c. + +#include "types.h" +#include "defs.h" +#include "traps.h" + +#define IOAPIC 0xFEC00000 // Default physical address of IO APIC + +#define REG_ID 0x00 // Register index: ID +#define REG_VER 0x01 // Register index: version +#define REG_TABLE 0x10 // Redirection table base + +// The redirection table starts at REG_TABLE and uses +// two registers to configure each interrupt. +// The first (low) register in a pair contains configuration bits. +// The second (high) register contains a bitmask telling which +// CPUs can serve that interrupt. +#define INT_DISABLED 0x00010000 // Interrupt disabled +#define INT_LEVEL 0x00008000 // Level-triggered (vs edge-) +#define INT_ACTIVELOW 0x00002000 // Active low (vs high) +#define INT_LOGICAL 0x00000800 // Destination is CPU id (vs APIC ID) + +volatile struct ioapic *ioapic; + +// IO APIC MMIO structure: write reg, then read or write data. +struct ioapic { + uint reg; + uint pad[3]; + uint data; +}; + +static uint ioapicread(int reg) { + ioapic->reg = reg; + return ioapic->data; +} + +static void ioapicwrite(int reg, uint data) { + ioapic->reg = reg; + ioapic->data = data; +} + +void ioapicinit(void) { + int i, id, maxintr; + + ioapic = (volatile struct ioapic*)IOAPIC; + maxintr = (ioapicread(REG_VER) >> 16) & 0xFF; + id = ioapicread(REG_ID) >> 24; + if (id != ioapicid) { + cprintf("ioapicinit: id isn't equal to ioapicid; not a MP\n"); + } + + // Mark all interrupts edge-triggered, active high, disabled, + // and not routed to any CPUs. + for (i = 0; i <= maxintr; i++) { + ioapicwrite(REG_TABLE + 2 * i, INT_DISABLED | (T_IRQ0 + i)); + ioapicwrite(REG_TABLE + 2 * i + 1, 0); + } +} + +void ioapicenable(int irq, int cpunum) { + // Mark interrupt edge-triggered, active high, + // enabled, and routed to the given cpunum, + // which happens to be that cpu's APIC ID. + ioapicwrite(REG_TABLE + 2 * irq, T_IRQ0 + irq); + ioapicwrite(REG_TABLE + 2 * irq + 1, cpunum << 24); +} diff --git a/ioapic.d b/ioapic.d new file mode 100644 index 0000000..997e68a --- /dev/null +++ b/ioapic.d @@ -0,0 +1 @@ +ioapic.o: ioapic.c /usr/include/stdc-predef.h types.h defs.h traps.h diff --git a/ioapic.o b/ioapic.o new file mode 100644 index 0000000..469e9b8 Binary files /dev/null and b/ioapic.o differ diff --git a/kalloc.c b/kalloc.c new file mode 100644 index 0000000..d1ef801 --- /dev/null +++ b/kalloc.c @@ -0,0 +1,93 @@ +// Physical memory allocator, intended to allocate +// memory for user processes, kernel stacks, page table pages, +// and pipe buffers. Allocates 4096-byte pages. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "spinlock.h" + +void freerange(void *vstart, void *vend); +extern char end[]; // first address after kernel loaded from ELF file + // defined by the kernel linker script in kernel.ld + +struct run { + struct run *next; +}; + +struct { + struct spinlock lock; + int use_lock; + struct run *freelist; +} kmem; + +// Initialization happens in two phases. +// 1. main() calls kinit1() while still using entrypgdir to place just +// the pages mapped by entrypgdir on free list. +// 2. main() calls kinit2() with the rest of the physical pages +// after installing a full page table that maps them on all cores. +void kinit1(void *vstart, void *vend) { + initlock(&kmem.lock, "kmem"); + kmem.use_lock = 0; + freerange(vstart, vend); +} + +void kinit2(void *vstart, void *vend) { + freerange(vstart, vend); + kmem.use_lock = 1; +} + +void freerange(void *vstart, void *vend) { + char *p; + p = (char*)PGROUNDUP((uint)vstart); + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { + kfree(p); + } +} + +// Free the page of physical memory pointed at by v, +// which normally should have been returned by a +// call to kalloc(). (The exception is when +// initializing the allocator; see kinit above.) +void kfree(char *v) { + struct run *r; + + if ((uint)v % PGSIZE || v < end || V2P(v) >= PHYSTOP) { + panic("kfree"); + } + + // Fill with junk to catch dangling refs. + memset(v, 1, PGSIZE); + + if (kmem.use_lock) { + acquire(&kmem.lock); + } + r = (struct run*)v; + r->next = kmem.freelist; + kmem.freelist = r; + if (kmem.use_lock) { + release(&kmem.lock); + } +} + +// Allocate one 4096-byte page of physical memory. +// Returns a pointer that the kernel can use. +// Returns 0 if the memory cannot be allocated. +char* kalloc(void) { + struct run *r; + + if (kmem.use_lock) { + acquire(&kmem.lock); + } + r = kmem.freelist; + if (r) { + kmem.freelist = r->next; + } + if (kmem.use_lock) { + release(&kmem.lock); + } + return (char*)r; +} + diff --git a/kalloc.d b/kalloc.d new file mode 100644 index 0000000..512c5db --- /dev/null +++ b/kalloc.d @@ -0,0 +1,2 @@ +kalloc.o: kalloc.c /usr/include/stdc-predef.h types.h defs.h param.h \ + memlayout.h mmu.h spinlock.h diff --git a/kalloc.o b/kalloc.o new file mode 100644 index 0000000..865d558 Binary files /dev/null and b/kalloc.o differ diff --git a/kbd.c b/kbd.c new file mode 100644 index 0000000..0426cb9 --- /dev/null +++ b/kbd.c @@ -0,0 +1,51 @@ +#include "types.h" +#include "x86.h" +#include "defs.h" +#include "kbd.h" + +int kbdgetc(void) { + static uint shift; + static uchar *charcode[4] = { + normalmap, shiftmap, ctlmap, ctlmap + }; + uint st, data, c; + + st = inb(KBSTATP); + if ((st & KBS_DIB) == 0) { + return -1; + } + data = inb(KBDATAP); + + if (data == 0xE0) { + shift |= E0ESC; + return 0; + } + else if (data & 0x80) { + // Key released + data = (shift & E0ESC ? data : data & 0x7F); + shift &= ~(shiftcode[data] | E0ESC); + return 0; + } + else if (shift & E0ESC) { + // Last character was an E0 escape; or with 0x80 + data |= 0x80; + shift &= ~E0ESC; + } + + shift |= shiftcode[data]; + shift ^= togglecode[data]; + c = charcode[shift & (CTL | SHIFT)][data]; + if (shift & CAPSLOCK) { + if ('a' <= c && c <= 'z') { + c += 'A' - 'a'; + } + else if ('A' <= c && c <= 'Z') { + c += 'a' - 'A'; + } + } + return c; +} + +void kbdintr(void) { + consoleintr(kbdgetc); +} diff --git a/kbd.d b/kbd.d new file mode 100644 index 0000000..92532ba --- /dev/null +++ b/kbd.d @@ -0,0 +1 @@ +kbd.o: kbd.c /usr/include/stdc-predef.h types.h x86.h defs.h kbd.h diff --git a/kbd.h b/kbd.h new file mode 100644 index 0000000..1d11783 --- /dev/null +++ b/kbd.h @@ -0,0 +1,112 @@ +// PC keyboard interface constants + +#define KBSTATP 0x64 // kbd controller status port(I) +#define KBS_DIB 0x01 // kbd data in buffer +#define KBDATAP 0x60 // kbd data port(I) + +#define NO 0 + +#define SHIFT (1 << 0) +#define CTL (1 << 1) +#define ALT (1 << 2) + +#define CAPSLOCK (1 << 3) +#define NUMLOCK (1 << 4) +#define SCROLLLOCK (1 << 5) + +#define E0ESC (1 << 6) + +// Special keycodes +#define KEY_HOME 0xE0 +#define KEY_END 0xE1 +#define KEY_UP 0xE2 +#define KEY_DN 0xE3 +#define KEY_LF 0xE4 +#define KEY_RT 0xE5 +#define KEY_PGUP 0xE6 +#define KEY_PGDN 0xE7 +#define KEY_INS 0xE8 +#define KEY_DEL 0xE9 + +// C('A') == Control-A +#define C(x) (x - '@') + +static uchar shiftcode[256] = +{ + [0x1D] CTL, + [0x2A] SHIFT, + [0x36] SHIFT, + [0x38] ALT, + [0x9D] CTL, + [0xB8] ALT +}; + +static uchar togglecode[256] = +{ + [0x3A] CAPSLOCK, + [0x45] NUMLOCK, + [0x46] SCROLLLOCK +}; + +static uchar normalmap[256] = +{ + NO, 0x1B, '1', '2', '3', '4', '5', '6', // 0x00 + '7', '8', '9', '0', '-', '=', '\b', '\t', + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 0x10 + 'o', 'p', '[', ']', '\n', NO, 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 0x20 + '\'', '`', NO, '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', NO, '*', // 0x30 + NO, ' ', NO, NO, NO, NO, NO, NO, + NO, NO, NO, NO, NO, NO, NO, '7', // 0x40 + '8', '9', '-', '4', '5', '6', '+', '1', + '2', '3', '0', '.', NO, NO, NO, NO, // 0x50 + [0x9C] '\n', // KP_Enter + [0xB5] '/', // KP_Div + [0xC8] KEY_UP, [0xD0] KEY_DN, + [0xC9] KEY_PGUP, [0xD1] KEY_PGDN, + [0xCB] KEY_LF, [0xCD] KEY_RT, + [0x97] KEY_HOME, [0xCF] KEY_END, + [0xD2] KEY_INS, [0xD3] KEY_DEL +}; + +static uchar shiftmap[256] = +{ + NO, 033, '!', '@', '#', '$', '%', '^', // 0x00 + '&', '*', '(', ')', '_', '+', '\b', '\t', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', // 0x10 + 'O', 'P', '{', '}', '\n', NO, 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 0x20 + '"', '~', NO, '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?', NO, '*', // 0x30 + NO, ' ', NO, NO, NO, NO, NO, NO, + NO, NO, NO, NO, NO, NO, NO, '7', // 0x40 + '8', '9', '-', '4', '5', '6', '+', '1', + '2', '3', '0', '.', NO, NO, NO, NO, // 0x50 + [0x9C] '\n', // KP_Enter + [0xB5] '/', // KP_Div + [0xC8] KEY_UP, [0xD0] KEY_DN, + [0xC9] KEY_PGUP, [0xD1] KEY_PGDN, + [0xCB] KEY_LF, [0xCD] KEY_RT, + [0x97] KEY_HOME, [0xCF] KEY_END, + [0xD2] KEY_INS, [0xD3] KEY_DEL +}; + +static uchar ctlmap[256] = +{ + NO, NO, NO, NO, NO, NO, NO, NO, + NO, NO, NO, NO, NO, NO, NO, NO, + C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'), + C('O'), C('P'), NO, NO, '\r', NO, C('A'), C('S'), + C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), NO, + NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'), + C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO, + [0x9C] '\r', // KP_Enter + [0xB5] C('/'), // KP_Div + [0xC8] KEY_UP, [0xD0] KEY_DN, + [0xC9] KEY_PGUP, [0xD1] KEY_PGDN, + [0xCB] KEY_LF, [0xCD] KEY_RT, + [0x97] KEY_HOME, [0xCF] KEY_END, + [0xD2] KEY_INS, [0xD3] KEY_DEL +}; + diff --git a/kbd.o b/kbd.o new file mode 100644 index 0000000..fffe14c Binary files /dev/null and b/kbd.o differ diff --git a/kernel b/kernel new file mode 100644 index 0000000..2e6eb67 Binary files /dev/null and b/kernel differ diff --git a/kernel.asm b/kernel.asm new file mode 100644 index 0000000..57b96ee --- /dev/null +++ b/kernel.asm @@ -0,0 +1,15968 @@ + +kernel: file format elf32-i386 + + +Disassembly of section .text: + +80100000 : +80100000: 02 b0 ad 1b 00 00 add 0x1bad(%eax),%dh +80100006: 00 00 add %al,(%eax) +80100008: fe 4f 52 decb 0x52(%edi) +8010000b: e4 .byte 0xe4 + +8010000c : + +# Entering xv6 on boot processor, with paging off. +.globl entry +entry: + # Turn on page size extension for 4Mbyte pages + movl %cr4, %eax +8010000c: 0f 20 e0 mov %cr4,%eax + orl $(CR4_PSE), %eax +8010000f: 83 c8 10 or $0x10,%eax + movl %eax, %cr4 +80100012: 0f 22 e0 mov %eax,%cr4 + # Set page directory + movl $(V2P_WO(entrypgdir)), %eax +80100015: b8 00 90 10 00 mov $0x109000,%eax + movl %eax, %cr3 +8010001a: 0f 22 d8 mov %eax,%cr3 + # Turn on paging. + movl %cr0, %eax +8010001d: 0f 20 c0 mov %cr0,%eax + orl $(CR0_PG|CR0_WP), %eax +80100020: 0d 00 00 01 80 or $0x80010000,%eax + movl %eax, %cr0 +80100025: 0f 22 c0 mov %eax,%cr0 + + # Set up the stack pointer. + movl $(stack + KSTACKSIZE), %esp +80100028: bc f0 54 11 80 mov $0x801154f0,%esp + + # Jump to main(), and switch to executing at + # high addresses. The indirect call is needed because + # the assembler produces a PC-relative instruction + # for a direct jump. + mov $main, %eax +8010002d: b8 80 31 10 80 mov $0x80103180,%eax + jmp *%eax +80100032: ff e0 jmp *%eax +80100034: 66 90 xchg %ax,%ax +80100036: 66 90 xchg %ax,%ax +80100038: 66 90 xchg %ax,%ax +8010003a: 66 90 xchg %ax,%ax +8010003c: 66 90 xchg %ax,%ax +8010003e: 66 90 xchg %ax,%ax + +80100040 : + // Linked list of all buffers, through prev/next. + // head.next is most recently used. + struct buf head; +} bcache; + +void binit(void) { +80100040: 55 push %ebp +80100041: 89 e5 mov %esp,%ebp +80100043: 53 push %ebx + initlock(&bcache.lock, "bcache"); + + // Create linked list of buffers + bcache.head.prev = &bcache.head; + bcache.head.next = &bcache.head; + for (b = bcache.buf; b < bcache.buf + NBUF; b++) { +80100044: bb 54 a5 10 80 mov $0x8010a554,%ebx +void binit(void) { +80100049: 83 ec 0c sub $0xc,%esp + initlock(&bcache.lock, "bcache"); +8010004c: 68 e0 73 10 80 push $0x801073e0 +80100051: 68 20 a5 10 80 push $0x8010a520 +80100056: e8 d5 44 00 00 call 80104530 + bcache.head.next = &bcache.head; +8010005b: 83 c4 10 add $0x10,%esp +8010005e: b8 1c ec 10 80 mov $0x8010ec1c,%eax + bcache.head.prev = &bcache.head; +80100063: c7 05 6c ec 10 80 1c movl $0x8010ec1c,0x8010ec6c +8010006a: ec 10 80 + bcache.head.next = &bcache.head; +8010006d: c7 05 70 ec 10 80 1c movl $0x8010ec1c,0x8010ec70 +80100074: ec 10 80 + for (b = bcache.buf; b < bcache.buf + NBUF; b++) { +80100077: eb 09 jmp 80100082 +80100079: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80100080: 89 d3 mov %edx,%ebx + b->next = bcache.head.next; +80100082: 89 43 54 mov %eax,0x54(%ebx) + b->prev = &bcache.head; + initsleeplock(&b->lock, "buffer"); +80100085: 83 ec 08 sub $0x8,%esp +80100088: 8d 43 0c lea 0xc(%ebx),%eax + b->prev = &bcache.head; +8010008b: c7 43 50 1c ec 10 80 movl $0x8010ec1c,0x50(%ebx) + initsleeplock(&b->lock, "buffer"); +80100092: 68 e7 73 10 80 push $0x801073e7 +80100097: 50 push %eax +80100098: e8 63 43 00 00 call 80104400 + bcache.head.next->prev = b; +8010009d: a1 70 ec 10 80 mov 0x8010ec70,%eax + for (b = bcache.buf; b < bcache.buf + NBUF; b++) { +801000a2: 8d 93 5c 02 00 00 lea 0x25c(%ebx),%edx +801000a8: 83 c4 10 add $0x10,%esp + bcache.head.next->prev = b; +801000ab: 89 58 50 mov %ebx,0x50(%eax) + bcache.head.next = b; +801000ae: 89 d8 mov %ebx,%eax +801000b0: 89 1d 70 ec 10 80 mov %ebx,0x8010ec70 + for (b = bcache.buf; b < bcache.buf + NBUF; b++) { +801000b6: 81 fb c0 e9 10 80 cmp $0x8010e9c0,%ebx +801000bc: 75 c2 jne 80100080 + } +} +801000be: 8b 5d fc mov -0x4(%ebp),%ebx +801000c1: c9 leave +801000c2: c3 ret +801000c3: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801000ca: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +801000d0 : + panic("bget: no buffers"); +} + +// Return a locked buf with the contents of the indicated block. + +struct buf*bread(uint dev, uint blockno) { +801000d0: 55 push %ebp +801000d1: 89 e5 mov %esp,%ebp +801000d3: 57 push %edi +801000d4: 56 push %esi +801000d5: 53 push %ebx +801000d6: 83 ec 18 sub $0x18,%esp +801000d9: 8b 75 08 mov 0x8(%ebp),%esi +801000dc: 8b 7d 0c mov 0xc(%ebp),%edi + acquire(&bcache.lock); +801000df: 68 20 a5 10 80 push $0x8010a520 +801000e4: e8 17 46 00 00 call 80104700 + for (b = bcache.head.next; b != &bcache.head; b = b->next) { +801000e9: 8b 1d 70 ec 10 80 mov 0x8010ec70,%ebx +801000ef: 83 c4 10 add $0x10,%esp +801000f2: 81 fb 1c ec 10 80 cmp $0x8010ec1c,%ebx +801000f8: 75 11 jne 8010010b +801000fa: eb 24 jmp 80100120 +801000fc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80100100: 8b 5b 54 mov 0x54(%ebx),%ebx +80100103: 81 fb 1c ec 10 80 cmp $0x8010ec1c,%ebx +80100109: 74 15 je 80100120 + if (b->dev == dev && b->blockno == blockno) { +8010010b: 3b 73 04 cmp 0x4(%ebx),%esi +8010010e: 75 f0 jne 80100100 +80100110: 3b 7b 08 cmp 0x8(%ebx),%edi +80100113: 75 eb jne 80100100 + b->refcnt++; +80100115: 83 43 4c 01 addl $0x1,0x4c(%ebx) + release(&bcache.lock); +80100119: eb 3f jmp 8010015a +8010011b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010011f: 90 nop + for (b = bcache.head.prev; b != &bcache.head; b = b->prev) { +80100120: 8b 1d 6c ec 10 80 mov 0x8010ec6c,%ebx +80100126: 81 fb 1c ec 10 80 cmp $0x8010ec1c,%ebx +8010012c: 75 0d jne 8010013b +8010012e: eb 6e jmp 8010019e +80100130: 8b 5b 50 mov 0x50(%ebx),%ebx +80100133: 81 fb 1c ec 10 80 cmp $0x8010ec1c,%ebx +80100139: 74 63 je 8010019e + if (b->refcnt == 0 && (b->flags & B_DIRTY) == 0) { +8010013b: 8b 43 4c mov 0x4c(%ebx),%eax +8010013e: 85 c0 test %eax,%eax +80100140: 75 ee jne 80100130 +80100142: f6 03 04 testb $0x4,(%ebx) +80100145: 75 e9 jne 80100130 + b->dev = dev; +80100147: 89 73 04 mov %esi,0x4(%ebx) + b->blockno = blockno; +8010014a: 89 7b 08 mov %edi,0x8(%ebx) + b->flags = 0; +8010014d: c7 03 00 00 00 00 movl $0x0,(%ebx) + b->refcnt = 1; +80100153: c7 43 4c 01 00 00 00 movl $0x1,0x4c(%ebx) + release(&bcache.lock); +8010015a: 83 ec 0c sub $0xc,%esp +8010015d: 68 20 a5 10 80 push $0x8010a520 +80100162: e8 39 45 00 00 call 801046a0 + acquiresleep(&b->lock); +80100167: 8d 43 0c lea 0xc(%ebx),%eax +8010016a: 89 04 24 mov %eax,(%esp) +8010016d: e8 ce 42 00 00 call 80104440 + return b; +80100172: 83 c4 10 add $0x10,%esp + struct buf *b; + + b = bget(dev, blockno); + if ((b->flags & B_VALID) == 0) { +80100175: f6 03 02 testb $0x2,(%ebx) +80100178: 74 0e je 80100188 + iderw(b); + } + return b; +} +8010017a: 8d 65 f4 lea -0xc(%ebp),%esp +8010017d: 89 d8 mov %ebx,%eax +8010017f: 5b pop %ebx +80100180: 5e pop %esi +80100181: 5f pop %edi +80100182: 5d pop %ebp +80100183: c3 ret +80100184: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + iderw(b); +80100188: 83 ec 0c sub $0xc,%esp +8010018b: 53 push %ebx +8010018c: e8 6f 22 00 00 call 80102400 +80100191: 83 c4 10 add $0x10,%esp +} +80100194: 8d 65 f4 lea -0xc(%ebp),%esp +80100197: 89 d8 mov %ebx,%eax +80100199: 5b pop %ebx +8010019a: 5e pop %esi +8010019b: 5f pop %edi +8010019c: 5d pop %ebp +8010019d: c3 ret + panic("bget: no buffers"); +8010019e: 83 ec 0c sub $0xc,%esp +801001a1: 68 ee 73 10 80 push $0x801073ee +801001a6: e8 e5 01 00 00 call 80100390 +801001ab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801001af: 90 nop + +801001b0 : + +// Write b's contents to disk. Must be locked. + +void bwrite(struct buf *b) { +801001b0: 55 push %ebp +801001b1: 89 e5 mov %esp,%ebp +801001b3: 53 push %ebx +801001b4: 83 ec 10 sub $0x10,%esp +801001b7: 8b 5d 08 mov 0x8(%ebp),%ebx + if (!holdingsleep(&b->lock)) { +801001ba: 8d 43 0c lea 0xc(%ebx),%eax +801001bd: 50 push %eax +801001be: e8 1d 43 00 00 call 801044e0 +801001c3: 83 c4 10 add $0x10,%esp +801001c6: 85 c0 test %eax,%eax +801001c8: 74 0f je 801001d9 + panic("bwrite"); + } + b->flags |= B_DIRTY; +801001ca: 83 0b 04 orl $0x4,(%ebx) + iderw(b); +801001cd: 89 5d 08 mov %ebx,0x8(%ebp) +} +801001d0: 8b 5d fc mov -0x4(%ebp),%ebx +801001d3: c9 leave + iderw(b); +801001d4: e9 27 22 00 00 jmp 80102400 + panic("bwrite"); +801001d9: 83 ec 0c sub $0xc,%esp +801001dc: 68 ff 73 10 80 push $0x801073ff +801001e1: e8 aa 01 00 00 call 80100390 +801001e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801001ed: 8d 76 00 lea 0x0(%esi),%esi + +801001f0 : + +// Release a locked buffer. +// Move to the head of the MRU list. + +void brelse(struct buf *b) { +801001f0: 55 push %ebp +801001f1: 89 e5 mov %esp,%ebp +801001f3: 56 push %esi +801001f4: 53 push %ebx +801001f5: 8b 5d 08 mov 0x8(%ebp),%ebx + if (!holdingsleep(&b->lock)) { +801001f8: 8d 73 0c lea 0xc(%ebx),%esi +801001fb: 83 ec 0c sub $0xc,%esp +801001fe: 56 push %esi +801001ff: e8 dc 42 00 00 call 801044e0 +80100204: 83 c4 10 add $0x10,%esp +80100207: 85 c0 test %eax,%eax +80100209: 74 66 je 80100271 + panic("brelse"); + } + + releasesleep(&b->lock); +8010020b: 83 ec 0c sub $0xc,%esp +8010020e: 56 push %esi +8010020f: e8 8c 42 00 00 call 801044a0 + + acquire(&bcache.lock); +80100214: c7 04 24 20 a5 10 80 movl $0x8010a520,(%esp) +8010021b: e8 e0 44 00 00 call 80104700 + b->refcnt--; +80100220: 8b 43 4c mov 0x4c(%ebx),%eax + if (b->refcnt == 0) { +80100223: 83 c4 10 add $0x10,%esp + b->refcnt--; +80100226: 83 e8 01 sub $0x1,%eax +80100229: 89 43 4c mov %eax,0x4c(%ebx) + if (b->refcnt == 0) { +8010022c: 85 c0 test %eax,%eax +8010022e: 75 2f jne 8010025f + // no one is waiting for it. + b->next->prev = b->prev; +80100230: 8b 43 54 mov 0x54(%ebx),%eax +80100233: 8b 53 50 mov 0x50(%ebx),%edx +80100236: 89 50 50 mov %edx,0x50(%eax) + b->prev->next = b->next; +80100239: 8b 43 50 mov 0x50(%ebx),%eax +8010023c: 8b 53 54 mov 0x54(%ebx),%edx +8010023f: 89 50 54 mov %edx,0x54(%eax) + b->next = bcache.head.next; +80100242: a1 70 ec 10 80 mov 0x8010ec70,%eax + b->prev = &bcache.head; +80100247: c7 43 50 1c ec 10 80 movl $0x8010ec1c,0x50(%ebx) + b->next = bcache.head.next; +8010024e: 89 43 54 mov %eax,0x54(%ebx) + bcache.head.next->prev = b; +80100251: a1 70 ec 10 80 mov 0x8010ec70,%eax +80100256: 89 58 50 mov %ebx,0x50(%eax) + bcache.head.next = b; +80100259: 89 1d 70 ec 10 80 mov %ebx,0x8010ec70 + } + + release(&bcache.lock); +8010025f: c7 45 08 20 a5 10 80 movl $0x8010a520,0x8(%ebp) +} +80100266: 8d 65 f8 lea -0x8(%ebp),%esp +80100269: 5b pop %ebx +8010026a: 5e pop %esi +8010026b: 5d pop %ebp + release(&bcache.lock); +8010026c: e9 2f 44 00 00 jmp 801046a0 + panic("brelse"); +80100271: 83 ec 0c sub $0xc,%esp +80100274: 68 06 74 10 80 push $0x80107406 +80100279: e8 12 01 00 00 call 80100390 +8010027e: 66 90 xchg %ax,%ax + +80100280 : + if (doprocdump) { + procdump(); // now call procdump() wo. cons.lock held + } +} + +int consoleread(struct inode *ip, char *dst, int n) { +80100280: 55 push %ebp +80100281: 89 e5 mov %esp,%ebp +80100283: 57 push %edi +80100284: 56 push %esi +80100285: 53 push %ebx +80100286: 83 ec 28 sub $0x28,%esp +80100289: 8b 5d 10 mov 0x10(%ebp),%ebx +8010028c: 8b 75 0c mov 0xc(%ebp),%esi + uint target; + int c; + + iunlock(ip); +8010028f: ff 75 08 push 0x8(%ebp) +80100292: e8 e9 16 00 00 call 80101980 + target = n; + acquire(&cons.lock); +80100297: c7 04 24 40 ef 10 80 movl $0x8010ef40,(%esp) + target = n; +8010029e: 89 5d e4 mov %ebx,-0x1c(%ebp) + acquire(&cons.lock); +801002a1: e8 5a 44 00 00 call 80104700 + while (n > 0) { +801002a6: 83 c4 10 add $0x10,%esp +801002a9: 85 db test %ebx,%ebx +801002ab: 0f 8e aa 00 00 00 jle 8010035b + while (input->r == input->w) { +801002b1: a1 80 ee 10 80 mov 0x8010ee80,%eax +801002b6: 8b 90 80 00 00 00 mov 0x80(%eax),%edx +801002bc: 3b 90 84 00 00 00 cmp 0x84(%eax),%edx +801002c2: 74 38 je 801002fc +801002c4: eb 6a jmp 80100330 +801002c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801002cd: 8d 76 00 lea 0x0(%esi),%esi + if (myproc()->killed) { + release(&cons.lock); + ilock(ip); + return -1; + } + sleep(&(input->r), &cons.lock); +801002d0: a1 80 ee 10 80 mov 0x8010ee80,%eax +801002d5: 83 ec 08 sub $0x8,%esp +801002d8: 68 40 ef 10 80 push $0x8010ef40 +801002dd: 83 e8 80 sub $0xffffff80,%eax +801002e0: 50 push %eax +801002e1: e8 ba 3e 00 00 call 801041a0 + while (input->r == input->w) { +801002e6: a1 80 ee 10 80 mov 0x8010ee80,%eax +801002eb: 83 c4 10 add $0x10,%esp +801002ee: 8b 90 80 00 00 00 mov 0x80(%eax),%edx +801002f4: 3b 90 84 00 00 00 cmp 0x84(%eax),%edx +801002fa: 75 34 jne 80100330 + if (myproc()->killed) { +801002fc: e8 cf 37 00 00 call 80103ad0 +80100301: 8b 48 24 mov 0x24(%eax),%ecx +80100304: 85 c9 test %ecx,%ecx +80100306: 74 c8 je 801002d0 + release(&cons.lock); +80100308: 83 ec 0c sub $0xc,%esp +8010030b: 68 40 ef 10 80 push $0x8010ef40 +80100310: e8 8b 43 00 00 call 801046a0 + ilock(ip); +80100315: 5a pop %edx +80100316: ff 75 08 push 0x8(%ebp) +80100319: e8 82 15 00 00 call 801018a0 + return -1; +8010031e: 83 c4 10 add $0x10,%esp + } + release(&cons.lock); + ilock(ip); + + return target - n; +} +80100321: 8d 65 f4 lea -0xc(%ebp),%esp + return -1; +80100324: b8 ff ff ff ff mov $0xffffffff,%eax +} +80100329: 5b pop %ebx +8010032a: 5e pop %esi +8010032b: 5f pop %edi +8010032c: 5d pop %ebp +8010032d: c3 ret +8010032e: 66 90 xchg %ax,%ax + c = input->buf[input->r++ % INPUT_BUF]; +80100330: 8d 4a 01 lea 0x1(%edx),%ecx +80100333: 89 88 80 00 00 00 mov %ecx,0x80(%eax) +80100339: 89 d1 mov %edx,%ecx +8010033b: 83 e1 7f and $0x7f,%ecx +8010033e: 0f be 3c 08 movsbl (%eax,%ecx,1),%edi +80100342: 89 f9 mov %edi,%ecx + if (c == C('D')) { // EOF +80100344: 80 f9 04 cmp $0x4,%cl +80100347: 74 38 je 80100381 + *dst++ = c; +80100349: 83 c6 01 add $0x1,%esi + --n; +8010034c: 83 eb 01 sub $0x1,%ebx + *dst++ = c; +8010034f: 88 4e ff mov %cl,-0x1(%esi) + if (c == '\n') { +80100352: 83 ff 0a cmp $0xa,%edi +80100355: 0f 85 4e ff ff ff jne 801002a9 + release(&cons.lock); +8010035b: 83 ec 0c sub $0xc,%esp +8010035e: 68 40 ef 10 80 push $0x8010ef40 +80100363: e8 38 43 00 00 call 801046a0 + ilock(ip); +80100368: 58 pop %eax +80100369: ff 75 08 push 0x8(%ebp) +8010036c: e8 2f 15 00 00 call 801018a0 + return target - n; +80100371: 8b 45 e4 mov -0x1c(%ebp),%eax +80100374: 83 c4 10 add $0x10,%esp +} +80100377: 8d 65 f4 lea -0xc(%ebp),%esp + return target - n; +8010037a: 29 d8 sub %ebx,%eax +} +8010037c: 5b pop %ebx +8010037d: 5e pop %esi +8010037e: 5f pop %edi +8010037f: 5d pop %ebp +80100380: c3 ret + if (n < target) { +80100381: 3b 5d e4 cmp -0x1c(%ebp),%ebx +80100384: 73 d5 jae 8010035b + input->r--; +80100386: 89 90 80 00 00 00 mov %edx,0x80(%eax) +8010038c: eb cd jmp 8010035b +8010038e: 66 90 xchg %ax,%ax + +80100390 : +void panic(char *s) { +80100390: 55 push %ebp +80100391: 89 e5 mov %esp,%ebp +80100393: 56 push %esi +80100394: 53 push %ebx +80100395: 83 ec 30 sub $0x30,%esp +static inline void loadgs(ushort v) { + asm volatile ("movw %0, %%gs" : : "r" (v)); +} + +static inline void cli(void) { + asm volatile ("cli"); +80100398: fa cli + cons.locking = 0; +80100399: c7 05 74 ef 10 80 00 movl $0x0,0x8010ef74 +801003a0: 00 00 00 + getcallerpcs(&s, pcs); +801003a3: 8d 5d d0 lea -0x30(%ebp),%ebx +801003a6: 8d 75 f8 lea -0x8(%ebp),%esi + cprintf("lapicid %d: panic: ", lapicid()); +801003a9: e8 62 26 00 00 call 80102a10 +801003ae: 83 ec 08 sub $0x8,%esp +801003b1: 50 push %eax +801003b2: 68 0d 74 10 80 push $0x8010740d +801003b7: e8 f4 02 00 00 call 801006b0 + cprintf(s); +801003bc: 58 pop %eax +801003bd: ff 75 08 push 0x8(%ebp) +801003c0: e8 eb 02 00 00 call 801006b0 + cprintf("\n"); +801003c5: c7 04 24 4f 7d 10 80 movl $0x80107d4f,(%esp) +801003cc: e8 df 02 00 00 call 801006b0 + getcallerpcs(&s, pcs); +801003d1: 8d 45 08 lea 0x8(%ebp),%eax +801003d4: 5a pop %edx +801003d5: 59 pop %ecx +801003d6: 53 push %ebx +801003d7: 50 push %eax +801003d8: e8 73 41 00 00 call 80104550 + for (i = 0; i < 10; i++) { +801003dd: 83 c4 10 add $0x10,%esp + cprintf(" %p", pcs[i]); +801003e0: 83 ec 08 sub $0x8,%esp +801003e3: ff 33 push (%ebx) + for (i = 0; i < 10; i++) { +801003e5: 83 c3 04 add $0x4,%ebx + cprintf(" %p", pcs[i]); +801003e8: 68 21 74 10 80 push $0x80107421 +801003ed: e8 be 02 00 00 call 801006b0 + for (i = 0; i < 10; i++) { +801003f2: 83 c4 10 add $0x10,%esp +801003f5: 39 f3 cmp %esi,%ebx +801003f7: 75 e7 jne 801003e0 + panicked = 1; // freeze other CPU +801003f9: c7 05 78 ef 10 80 01 movl $0x1,0x8010ef78 +80100400: 00 00 00 + for (;;) { +80100403: eb fe jmp 80100403 +80100405: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010040c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80100410 : +void consputc(int c) { +80100410: 55 push %ebp +80100411: 89 e5 mov %esp,%ebp +80100413: 57 push %edi +80100414: 56 push %esi +80100415: 53 push %ebx +80100416: 89 c3 mov %eax,%ebx +80100418: 83 ec 1c sub $0x1c,%esp + if (c == BACKSPACE) { +8010041b: 3d 00 01 00 00 cmp $0x100,%eax +80100420: 0f 84 ea 00 00 00 je 80100510 + uartputc(c); +80100426: 83 ec 0c sub $0xc,%esp +80100429: 50 push %eax +8010042a: e8 a1 5a 00 00 call 80105ed0 +8010042f: 83 c4 10 add $0x10,%esp + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80100432: bf d4 03 00 00 mov $0x3d4,%edi +80100437: b8 0e 00 00 00 mov $0xe,%eax +8010043c: 89 fa mov %edi,%edx +8010043e: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +8010043f: be d5 03 00 00 mov $0x3d5,%esi +80100444: 89 f2 mov %esi,%edx +80100446: ec in (%dx),%al + pos = inb(CRTPORT + 1) << 8; +80100447: 0f b6 c8 movzbl %al,%ecx + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +8010044a: 89 fa mov %edi,%edx +8010044c: b8 0f 00 00 00 mov $0xf,%eax +80100451: c1 e1 08 shl $0x8,%ecx +80100454: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80100455: 89 f2 mov %esi,%edx +80100457: ec in (%dx),%al + pos |= inb(CRTPORT + 1); +80100458: 0f b6 c0 movzbl %al,%eax +8010045b: 09 c8 or %ecx,%eax + if (c == '\n') { +8010045d: 83 fb 0a cmp $0xa,%ebx +80100460: 0f 84 92 00 00 00 je 801004f8 + else if (c == BACKSPACE) { +80100466: 81 fb 00 01 00 00 cmp $0x100,%ebx +8010046c: 74 72 je 801004e0 + crt[pos++] = (c & 0xff) | 0x0700; // black on white +8010046e: 0f b6 db movzbl %bl,%ebx +80100471: 8d 70 01 lea 0x1(%eax),%esi +80100474: 80 cf 07 or $0x7,%bh +80100477: 66 89 9c 00 00 80 0b mov %bx,-0x7ff48000(%eax,%eax,1) +8010047e: 80 + if (pos < 0 || pos > 25 * 80) { +8010047f: 81 fe d0 07 00 00 cmp $0x7d0,%esi +80100485: 0f 8f fb 00 00 00 jg 80100586 + if ((pos / 80) >= 24) { // Scroll up. +8010048b: 81 fe 7f 07 00 00 cmp $0x77f,%esi +80100491: 0f 8f a9 00 00 00 jg 80100540 + outb(CRTPORT + 1, pos >> 8); +80100497: 89 f0 mov %esi,%eax + crt[pos] = ' ' | 0x0700; +80100499: 8d b4 36 00 80 0b 80 lea -0x7ff48000(%esi,%esi,1),%esi + outb(CRTPORT + 1, pos); +801004a0: 88 45 e7 mov %al,-0x19(%ebp) + outb(CRTPORT + 1, pos >> 8); +801004a3: 0f b6 fc movzbl %ah,%edi + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +801004a6: bb d4 03 00 00 mov $0x3d4,%ebx +801004ab: b8 0e 00 00 00 mov $0xe,%eax +801004b0: 89 da mov %ebx,%edx +801004b2: ee out %al,(%dx) +801004b3: b9 d5 03 00 00 mov $0x3d5,%ecx +801004b8: 89 f8 mov %edi,%eax +801004ba: 89 ca mov %ecx,%edx +801004bc: ee out %al,(%dx) +801004bd: b8 0f 00 00 00 mov $0xf,%eax +801004c2: 89 da mov %ebx,%edx +801004c4: ee out %al,(%dx) +801004c5: 0f b6 45 e7 movzbl -0x19(%ebp),%eax +801004c9: 89 ca mov %ecx,%edx +801004cb: ee out %al,(%dx) + crt[pos] = ' ' | 0x0700; +801004cc: b8 20 07 00 00 mov $0x720,%eax +801004d1: 66 89 06 mov %ax,(%esi) +} +801004d4: 8d 65 f4 lea -0xc(%ebp),%esp +801004d7: 5b pop %ebx +801004d8: 5e pop %esi +801004d9: 5f pop %edi +801004da: 5d pop %ebp +801004db: c3 ret +801004dc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + --pos; +801004e0: 8d 70 ff lea -0x1(%eax),%esi + if (pos > 0) { +801004e3: 85 c0 test %eax,%eax +801004e5: 75 98 jne 8010047f +801004e7: c6 45 e7 00 movb $0x0,-0x19(%ebp) +801004eb: be 00 80 0b 80 mov $0x800b8000,%esi +801004f0: 31 ff xor %edi,%edi +801004f2: eb b2 jmp 801004a6 +801004f4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + pos += 80 - pos % 80; +801004f8: ba cd cc cc cc mov $0xcccccccd,%edx +801004fd: f7 e2 mul %edx +801004ff: c1 ea 06 shr $0x6,%edx +80100502: 8d 04 92 lea (%edx,%edx,4),%eax +80100505: c1 e0 04 shl $0x4,%eax +80100508: 8d 70 50 lea 0x50(%eax),%esi +8010050b: e9 6f ff ff ff jmp 8010047f + uartputc('\b'); +80100510: 83 ec 0c sub $0xc,%esp +80100513: 6a 08 push $0x8 +80100515: e8 b6 59 00 00 call 80105ed0 + uartputc(' '); +8010051a: c7 04 24 20 00 00 00 movl $0x20,(%esp) +80100521: e8 aa 59 00 00 call 80105ed0 + uartputc('\b'); +80100526: c7 04 24 08 00 00 00 movl $0x8,(%esp) +8010052d: e8 9e 59 00 00 call 80105ed0 +80100532: 83 c4 10 add $0x10,%esp +80100535: e9 f8 fe ff ff jmp 80100432 +8010053a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + memmove(crt, crt + 80, sizeof(crt[0]) * 23 * 80); +80100540: 83 ec 04 sub $0x4,%esp + pos -= 80; +80100543: 8d 5e b0 lea -0x50(%esi),%ebx + memset(crt + pos, 0, sizeof(crt[0]) * (24 * 80 - pos)); +80100546: 8d b4 36 60 7f 0b 80 lea -0x7ff480a0(%esi,%esi,1),%esi + outb(CRTPORT + 1, pos); +8010054d: bf 07 00 00 00 mov $0x7,%edi + memmove(crt, crt + 80, sizeof(crt[0]) * 23 * 80); +80100552: 68 60 0e 00 00 push $0xe60 +80100557: 68 a0 80 0b 80 push $0x800b80a0 +8010055c: 68 00 80 0b 80 push $0x800b8000 +80100561: e8 fa 42 00 00 call 80104860 + memset(crt + pos, 0, sizeof(crt[0]) * (24 * 80 - pos)); +80100566: b8 80 07 00 00 mov $0x780,%eax +8010056b: 83 c4 0c add $0xc,%esp +8010056e: 29 d8 sub %ebx,%eax +80100570: 01 c0 add %eax,%eax +80100572: 50 push %eax +80100573: 6a 00 push $0x0 +80100575: 56 push %esi +80100576: e8 45 42 00 00 call 801047c0 + outb(CRTPORT + 1, pos); +8010057b: 88 5d e7 mov %bl,-0x19(%ebp) +8010057e: 83 c4 10 add $0x10,%esp +80100581: e9 20 ff ff ff jmp 801004a6 + panic("pos under/overflow"); +80100586: 83 ec 0c sub $0xc,%esp +80100589: 68 25 74 10 80 push $0x80107425 +8010058e: e8 fd fd ff ff call 80100390 +80100593: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010059a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +801005a0 : + +int consolewrite(struct inode *ip, char *buf, int n) { +801005a0: 55 push %ebp +801005a1: 89 e5 mov %esp,%ebp +801005a3: 57 push %edi +801005a4: 56 push %esi +801005a5: 53 push %ebx +801005a6: 83 ec 18 sub $0x18,%esp + int i; + + iunlock(ip); +801005a9: ff 75 08 push 0x8(%ebp) +int consolewrite(struct inode *ip, char *buf, int n) { +801005ac: 8b 75 10 mov 0x10(%ebp),%esi + iunlock(ip); +801005af: e8 cc 13 00 00 call 80101980 + acquire(&cons.lock); +801005b4: c7 04 24 40 ef 10 80 movl $0x8010ef40,(%esp) +801005bb: e8 40 41 00 00 call 80104700 + for (i = 0; i < n; i++) { +801005c0: 83 c4 10 add $0x10,%esp +801005c3: 85 f6 test %esi,%esi +801005c5: 7e 25 jle 801005ec +801005c7: 8b 5d 0c mov 0xc(%ebp),%ebx +801005ca: 8d 3c 33 lea (%ebx,%esi,1),%edi + if (panicked) { +801005cd: 8b 15 78 ef 10 80 mov 0x8010ef78,%edx + consputc(buf[i] & 0xff); +801005d3: 0f b6 03 movzbl (%ebx),%eax + if (panicked) { +801005d6: 85 d2 test %edx,%edx +801005d8: 74 06 je 801005e0 + asm volatile ("cli"); +801005da: fa cli + for (;;) { +801005db: eb fe jmp 801005db +801005dd: 8d 76 00 lea 0x0(%esi),%esi +801005e0: e8 2b fe ff ff call 80100410 + for (i = 0; i < n; i++) { +801005e5: 83 c3 01 add $0x1,%ebx +801005e8: 39 df cmp %ebx,%edi +801005ea: 75 e1 jne 801005cd + } + release(&cons.lock); +801005ec: 83 ec 0c sub $0xc,%esp +801005ef: 68 40 ef 10 80 push $0x8010ef40 +801005f4: e8 a7 40 00 00 call 801046a0 + ilock(ip); +801005f9: 58 pop %eax +801005fa: ff 75 08 push 0x8(%ebp) +801005fd: e8 9e 12 00 00 call 801018a0 + + return n; +} +80100602: 8d 65 f4 lea -0xc(%ebp),%esp +80100605: 89 f0 mov %esi,%eax +80100607: 5b pop %ebx +80100608: 5e pop %esi +80100609: 5f pop %edi +8010060a: 5d pop %ebp +8010060b: c3 ret +8010060c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80100610 : +static void printint(int xx, int base, int sign) { +80100610: 55 push %ebp +80100611: 89 e5 mov %esp,%ebp +80100613: 57 push %edi +80100614: 56 push %esi +80100615: 53 push %ebx +80100616: 83 ec 2c sub $0x2c,%esp +80100619: 89 55 d4 mov %edx,-0x2c(%ebp) +8010061c: 89 4d d0 mov %ecx,-0x30(%ebp) + if (sign && (sign = xx < 0)) { +8010061f: 85 c9 test %ecx,%ecx +80100621: 74 04 je 80100627 +80100623: 85 c0 test %eax,%eax +80100625: 78 6d js 80100694 + x = xx; +80100627: c7 45 d0 00 00 00 00 movl $0x0,-0x30(%ebp) +8010062e: 89 c1 mov %eax,%ecx + i = 0; +80100630: 31 db xor %ebx,%ebx +80100632: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + buf[i++] = digits[x % base]; +80100638: 89 c8 mov %ecx,%eax +8010063a: 31 d2 xor %edx,%edx +8010063c: 89 de mov %ebx,%esi +8010063e: 89 cf mov %ecx,%edi +80100640: f7 75 d4 divl -0x2c(%ebp) +80100643: 8d 5b 01 lea 0x1(%ebx),%ebx +80100646: 0f b6 92 50 74 10 80 movzbl -0x7fef8bb0(%edx),%edx + while ((x /= base) != 0); +8010064d: 89 c1 mov %eax,%ecx + buf[i++] = digits[x % base]; +8010064f: 88 54 1d d7 mov %dl,-0x29(%ebp,%ebx,1) + while ((x /= base) != 0); +80100653: 3b 7d d4 cmp -0x2c(%ebp),%edi +80100656: 73 e0 jae 80100638 + if (sign) { +80100658: 8b 4d d0 mov -0x30(%ebp),%ecx +8010065b: 85 c9 test %ecx,%ecx +8010065d: 74 0c je 8010066b + buf[i++] = '-'; +8010065f: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; +80100664: 89 de mov %ebx,%esi + buf[i++] = '-'; +80100666: ba 2d 00 00 00 mov $0x2d,%edx + while (--i >= 0) { +8010066b: 8d 5c 35 d7 lea -0x29(%ebp,%esi,1),%ebx +8010066f: 0f be c2 movsbl %dl,%eax + if (panicked) { +80100672: 8b 15 78 ef 10 80 mov 0x8010ef78,%edx +80100678: 85 d2 test %edx,%edx +8010067a: 74 04 je 80100680 +8010067c: fa cli + for (;;) { +8010067d: eb fe jmp 8010067d +8010067f: 90 nop +80100680: e8 8b fd ff ff call 80100410 + while (--i >= 0) { +80100685: 8d 45 d7 lea -0x29(%ebp),%eax +80100688: 39 c3 cmp %eax,%ebx +8010068a: 74 0e je 8010069a + consputc(buf[i]); +8010068c: 0f be 03 movsbl (%ebx),%eax +8010068f: 83 eb 01 sub $0x1,%ebx +80100692: eb de jmp 80100672 + x = -xx; +80100694: f7 d8 neg %eax +80100696: 89 c1 mov %eax,%ecx +80100698: eb 96 jmp 80100630 +} +8010069a: 83 c4 2c add $0x2c,%esp +8010069d: 5b pop %ebx +8010069e: 5e pop %esi +8010069f: 5f pop %edi +801006a0: 5d pop %ebp +801006a1: c3 ret +801006a2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801006a9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +801006b0 : +void cprintf(char *fmt, ...) { +801006b0: 55 push %ebp +801006b1: 89 e5 mov %esp,%ebp +801006b3: 57 push %edi +801006b4: 56 push %esi +801006b5: 53 push %ebx +801006b6: 83 ec 1c sub $0x1c,%esp + locking = cons.locking; +801006b9: a1 74 ef 10 80 mov 0x8010ef74,%eax +801006be: 89 45 e4 mov %eax,-0x1c(%ebp) + if (locking) { +801006c1: 85 c0 test %eax,%eax +801006c3: 0f 85 27 01 00 00 jne 801007f0 + if (fmt == 0) { +801006c9: 8b 75 08 mov 0x8(%ebp),%esi +801006cc: 85 f6 test %esi,%esi +801006ce: 0f 84 ac 01 00 00 je 80100880 + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { +801006d4: 0f b6 06 movzbl (%esi),%eax + argp = (uint*)(void*)(&fmt + 1); +801006d7: 8d 7d 0c lea 0xc(%ebp),%edi + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { +801006da: 31 db xor %ebx,%ebx +801006dc: 85 c0 test %eax,%eax +801006de: 74 56 je 80100736 + if (c != '%') { +801006e0: 83 f8 25 cmp $0x25,%eax +801006e3: 0f 85 cf 00 00 00 jne 801007b8 + c = fmt[++i] & 0xff; +801006e9: 83 c3 01 add $0x1,%ebx +801006ec: 0f b6 14 1e movzbl (%esi,%ebx,1),%edx + if (c == 0) { +801006f0: 85 d2 test %edx,%edx +801006f2: 74 42 je 80100736 + switch (c) { +801006f4: 83 fa 70 cmp $0x70,%edx +801006f7: 0f 84 90 00 00 00 je 8010078d +801006fd: 7f 51 jg 80100750 +801006ff: 83 fa 25 cmp $0x25,%edx +80100702: 0f 84 c0 00 00 00 je 801007c8 +80100708: 83 fa 64 cmp $0x64,%edx +8010070b: 0f 85 f4 00 00 00 jne 80100805 + printint(*argp++, 10, 1); +80100711: 8d 47 04 lea 0x4(%edi),%eax +80100714: b9 01 00 00 00 mov $0x1,%ecx +80100719: ba 0a 00 00 00 mov $0xa,%edx +8010071e: 89 45 e0 mov %eax,-0x20(%ebp) +80100721: 8b 07 mov (%edi),%eax +80100723: e8 e8 fe ff ff call 80100610 +80100728: 8b 7d e0 mov -0x20(%ebp),%edi + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { +8010072b: 83 c3 01 add $0x1,%ebx +8010072e: 0f b6 04 1e movzbl (%esi,%ebx,1),%eax +80100732: 85 c0 test %eax,%eax +80100734: 75 aa jne 801006e0 + if (locking) { +80100736: 8b 45 e4 mov -0x1c(%ebp),%eax +80100739: 85 c0 test %eax,%eax +8010073b: 0f 85 22 01 00 00 jne 80100863 +} +80100741: 8d 65 f4 lea -0xc(%ebp),%esp +80100744: 5b pop %ebx +80100745: 5e pop %esi +80100746: 5f pop %edi +80100747: 5d pop %ebp +80100748: c3 ret +80100749: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + switch (c) { +80100750: 83 fa 73 cmp $0x73,%edx +80100753: 75 33 jne 80100788 + if ((s = (char*)*argp++) == 0) { +80100755: 8d 47 04 lea 0x4(%edi),%eax +80100758: 8b 3f mov (%edi),%edi +8010075a: 89 45 e0 mov %eax,-0x20(%ebp) +8010075d: 85 ff test %edi,%edi +8010075f: 0f 84 e3 00 00 00 je 80100848 + for (; *s; s++) { +80100765: 0f be 07 movsbl (%edi),%eax +80100768: 84 c0 test %al,%al +8010076a: 0f 84 08 01 00 00 je 80100878 + if (panicked) { +80100770: 8b 15 78 ef 10 80 mov 0x8010ef78,%edx +80100776: 85 d2 test %edx,%edx +80100778: 0f 84 b2 00 00 00 je 80100830 +8010077e: fa cli + for (;;) { +8010077f: eb fe jmp 8010077f +80100781: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + switch (c) { +80100788: 83 fa 78 cmp $0x78,%edx +8010078b: 75 78 jne 80100805 + printint(*argp++, 16, 0); +8010078d: 8d 47 04 lea 0x4(%edi),%eax +80100790: 31 c9 xor %ecx,%ecx +80100792: ba 10 00 00 00 mov $0x10,%edx + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { +80100797: 83 c3 01 add $0x1,%ebx + printint(*argp++, 16, 0); +8010079a: 89 45 e0 mov %eax,-0x20(%ebp) +8010079d: 8b 07 mov (%edi),%eax +8010079f: e8 6c fe ff ff call 80100610 + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { +801007a4: 0f b6 04 1e movzbl (%esi,%ebx,1),%eax + printint(*argp++, 16, 0); +801007a8: 8b 7d e0 mov -0x20(%ebp),%edi + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { +801007ab: 85 c0 test %eax,%eax +801007ad: 0f 85 2d ff ff ff jne 801006e0 +801007b3: eb 81 jmp 80100736 +801007b5: 8d 76 00 lea 0x0(%esi),%esi + if (panicked) { +801007b8: 8b 0d 78 ef 10 80 mov 0x8010ef78,%ecx +801007be: 85 c9 test %ecx,%ecx +801007c0: 74 14 je 801007d6 +801007c2: fa cli + for (;;) { +801007c3: eb fe jmp 801007c3 +801007c5: 8d 76 00 lea 0x0(%esi),%esi + if (panicked) { +801007c8: a1 78 ef 10 80 mov 0x8010ef78,%eax +801007cd: 85 c0 test %eax,%eax +801007cf: 75 6c jne 8010083d +801007d1: b8 25 00 00 00 mov $0x25,%eax +801007d6: e8 35 fc ff ff call 80100410 + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { +801007db: 83 c3 01 add $0x1,%ebx +801007de: 0f b6 04 1e movzbl (%esi,%ebx,1),%eax +801007e2: 85 c0 test %eax,%eax +801007e4: 0f 85 f6 fe ff ff jne 801006e0 +801007ea: e9 47 ff ff ff jmp 80100736 +801007ef: 90 nop + acquire(&cons.lock); +801007f0: 83 ec 0c sub $0xc,%esp +801007f3: 68 40 ef 10 80 push $0x8010ef40 +801007f8: e8 03 3f 00 00 call 80104700 +801007fd: 83 c4 10 add $0x10,%esp +80100800: e9 c4 fe ff ff jmp 801006c9 + if (panicked) { +80100805: 8b 0d 78 ef 10 80 mov 0x8010ef78,%ecx +8010080b: 85 c9 test %ecx,%ecx +8010080d: 75 31 jne 80100840 +8010080f: b8 25 00 00 00 mov $0x25,%eax +80100814: 89 55 e0 mov %edx,-0x20(%ebp) +80100817: e8 f4 fb ff ff call 80100410 +8010081c: 8b 15 78 ef 10 80 mov 0x8010ef78,%edx +80100822: 85 d2 test %edx,%edx +80100824: 8b 55 e0 mov -0x20(%ebp),%edx +80100827: 74 2e je 80100857 +80100829: fa cli + for (;;) { +8010082a: eb fe jmp 8010082a +8010082c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80100830: e8 db fb ff ff call 80100410 + for (; *s; s++) { +80100835: 83 c7 01 add $0x1,%edi +80100838: e9 28 ff ff ff jmp 80100765 +8010083d: fa cli + for (;;) { +8010083e: eb fe jmp 8010083e +80100840: fa cli +80100841: eb fe jmp 80100841 +80100843: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80100847: 90 nop + s = "(null)"; +80100848: bf 38 74 10 80 mov $0x80107438,%edi + for (; *s; s++) { +8010084d: b8 28 00 00 00 mov $0x28,%eax +80100852: e9 19 ff ff ff jmp 80100770 +80100857: 89 d0 mov %edx,%eax +80100859: e8 b2 fb ff ff call 80100410 +8010085e: e9 c8 fe ff ff jmp 8010072b + release(&cons.lock); +80100863: 83 ec 0c sub $0xc,%esp +80100866: 68 40 ef 10 80 push $0x8010ef40 +8010086b: e8 30 3e 00 00 call 801046a0 +80100870: 83 c4 10 add $0x10,%esp +} +80100873: e9 c9 fe ff ff jmp 80100741 + if ((s = (char*)*argp++) == 0) { +80100878: 8b 7d e0 mov -0x20(%ebp),%edi +8010087b: e9 ab fe ff ff jmp 8010072b + panic("null fmt"); +80100880: 83 ec 0c sub $0xc,%esp +80100883: 68 3f 74 10 80 push $0x8010743f +80100888: e8 03 fb ff ff call 80100390 +8010088d: 8d 76 00 lea 0x0(%esi),%esi + +80100890 : +int consoleget(void) { +80100890: 55 push %ebp +80100891: 89 e5 mov %esp,%ebp +80100893: 83 ec 24 sub $0x24,%esp + acquire(&cons.lock); +80100896: 68 40 ef 10 80 push $0x8010ef40 +8010089b: e8 60 3e 00 00 call 80104700 + while ((c = kbdgetc()) <= 0) { +801008a0: 83 c4 10 add $0x10,%esp +801008a3: eb 05 jmp 801008aa +801008a5: 8d 76 00 lea 0x0(%esi),%esi + if (c == 0) { +801008a8: 74 26 je 801008d0 + while ((c = kbdgetc()) <= 0) { +801008aa: e8 61 1f 00 00 call 80102810 +801008af: 85 c0 test %eax,%eax +801008b1: 7e f5 jle 801008a8 + release(&cons.lock); +801008b3: 83 ec 0c sub $0xc,%esp +801008b6: 89 45 f4 mov %eax,-0xc(%ebp) +801008b9: 68 40 ef 10 80 push $0x8010ef40 +801008be: e8 dd 3d 00 00 call 801046a0 +} +801008c3: 8b 45 f4 mov -0xc(%ebp),%eax +801008c6: c9 leave +801008c7: c3 ret +801008c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801008cf: 90 nop + c = kbdgetc(); +801008d0: e8 3b 1f 00 00 call 80102810 +801008d5: eb d3 jmp 801008aa +801008d7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801008de: 66 90 xchg %ax,%ax + +801008e0 : +void consoleintr(int (*getc)(void)) { +801008e0: 55 push %ebp +801008e1: 89 e5 mov %esp,%ebp +801008e3: 57 push %edi +801008e4: 56 push %esi + int c, doprocdump = 0; +801008e5: 31 f6 xor %esi,%esi +void consoleintr(int (*getc)(void)) { +801008e7: 53 push %ebx +801008e8: 83 ec 28 sub $0x28,%esp +801008eb: 8b 7d 08 mov 0x8(%ebp),%edi + acquire(&cons.lock); +801008ee: 68 40 ef 10 80 push $0x8010ef40 +801008f3: e8 08 3e 00 00 call 80104700 + while ((c = getc()) >= 0) { +801008f8: 83 c4 10 add $0x10,%esp +801008fb: eb 1a jmp 80100917 +801008fd: 8d 76 00 lea 0x0(%esi),%esi + switch (c) { +80100900: 83 fb 08 cmp $0x8,%ebx +80100903: 0f 84 07 01 00 00 je 80100a10 +80100909: 83 fb 10 cmp $0x10,%ebx +8010090c: 0f 85 4a 01 00 00 jne 80100a5c +80100912: be 01 00 00 00 mov $0x1,%esi + while ((c = getc()) >= 0) { +80100917: ff d7 call *%edi +80100919: 89 c3 mov %eax,%ebx +8010091b: 85 c0 test %eax,%eax +8010091d: 0f 88 1d 01 00 00 js 80100a40 + switch (c) { +80100923: 83 fb 15 cmp $0x15,%ebx +80100926: 0f 84 9e 00 00 00 je 801009ca +8010092c: 7e d2 jle 80100900 +8010092e: 83 fb 7f cmp $0x7f,%ebx +80100931: 0f 84 d9 00 00 00 je 80100a10 + if (c != 0 && input->e - input->r < INPUT_BUF) { +80100937: 8b 15 80 ee 10 80 mov 0x8010ee80,%edx +8010093d: 8b 82 88 00 00 00 mov 0x88(%edx),%eax +80100943: 89 c1 mov %eax,%ecx +80100945: 2b 8a 80 00 00 00 sub 0x80(%edx),%ecx +8010094b: 83 f9 7f cmp $0x7f,%ecx +8010094e: 77 c7 ja 80100917 + if (panicked) { +80100950: 8b 0d 78 ef 10 80 mov 0x8010ef78,%ecx +80100956: 89 4d e4 mov %ecx,-0x1c(%ebp) + input->buf[input->e++ % INPUT_BUF] = c; +80100959: 8d 48 01 lea 0x1(%eax),%ecx +8010095c: 83 e0 7f and $0x7f,%eax +8010095f: 89 8a 88 00 00 00 mov %ecx,0x88(%edx) + c = (c == '\r') ? '\n' : c; +80100965: 83 fb 0d cmp $0xd,%ebx +80100968: 0f 84 1d 01 00 00 je 80100a8b + input->buf[input->e++ % INPUT_BUF] = c; +8010096e: 88 1c 02 mov %bl,(%edx,%eax,1) + if (panicked) { +80100971: 8b 55 e4 mov -0x1c(%ebp),%edx +80100974: 85 d2 test %edx,%edx +80100976: 0f 85 1a 01 00 00 jne 80100a96 +8010097c: 89 d8 mov %ebx,%eax +8010097e: e8 8d fa ff ff call 80100410 + if (c == '\n' || c == C('D') || input->e == input->r + INPUT_BUF) { +80100983: a1 80 ee 10 80 mov 0x8010ee80,%eax +80100988: 83 fb 0a cmp $0xa,%ebx +8010098b: 0f 84 1e 01 00 00 je 80100aaf +80100991: 83 fb 04 cmp $0x4,%ebx +80100994: 0f 84 15 01 00 00 je 80100aaf +8010099a: 8b 88 80 00 00 00 mov 0x80(%eax),%ecx +801009a0: 8d 91 80 00 00 00 lea 0x80(%ecx),%edx +801009a6: 39 90 88 00 00 00 cmp %edx,0x88(%eax) +801009ac: 0f 85 65 ff ff ff jne 80100917 +801009b2: e9 fe 00 00 00 jmp 80100ab5 +801009b7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801009be: 66 90 xchg %ax,%ax +801009c0: b8 00 01 00 00 mov $0x100,%eax +801009c5: e8 46 fa ff ff call 80100410 + while (input->e != input->w && +801009ca: 8b 15 80 ee 10 80 mov 0x8010ee80,%edx +801009d0: 8b 82 88 00 00 00 mov 0x88(%edx),%eax +801009d6: 3b 82 84 00 00 00 cmp 0x84(%edx),%eax +801009dc: 0f 84 35 ff ff ff je 80100917 + input->buf[(input->e - 1) % INPUT_BUF] != '\n') { +801009e2: 83 e8 01 sub $0x1,%eax +801009e5: 89 c1 mov %eax,%ecx +801009e7: 83 e1 7f and $0x7f,%ecx + while (input->e != input->w && +801009ea: 80 3c 0a 0a cmpb $0xa,(%edx,%ecx,1) +801009ee: 0f 84 23 ff ff ff je 80100917 + if (panicked) { +801009f4: 8b 1d 78 ef 10 80 mov 0x8010ef78,%ebx + input->e--; +801009fa: 89 82 88 00 00 00 mov %eax,0x88(%edx) + if (panicked) { +80100a00: 85 db test %ebx,%ebx +80100a02: 74 bc je 801009c0 +80100a04: fa cli + for (;;) { +80100a05: eb fe jmp 80100a05 +80100a07: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80100a0e: 66 90 xchg %ax,%ax + if (input->e != input->w) { +80100a10: a1 80 ee 10 80 mov 0x8010ee80,%eax +80100a15: 8b 90 88 00 00 00 mov 0x88(%eax),%edx +80100a1b: 3b 90 84 00 00 00 cmp 0x84(%eax),%edx +80100a21: 0f 84 f0 fe ff ff je 80100917 + if (panicked) { +80100a27: 8b 0d 78 ef 10 80 mov 0x8010ef78,%ecx + input->e--; +80100a2d: 83 ea 01 sub $0x1,%edx +80100a30: 89 90 88 00 00 00 mov %edx,0x88(%eax) + if (panicked) { +80100a36: 85 c9 test %ecx,%ecx +80100a38: 74 36 je 80100a70 +80100a3a: fa cli + for (;;) { +80100a3b: eb fe jmp 80100a3b +80100a3d: 8d 76 00 lea 0x0(%esi),%esi + release(&cons.lock); +80100a40: 83 ec 0c sub $0xc,%esp +80100a43: 68 40 ef 10 80 push $0x8010ef40 +80100a48: e8 53 3c 00 00 call 801046a0 + if (doprocdump) { +80100a4d: 83 c4 10 add $0x10,%esp +80100a50: 85 f6 test %esi,%esi +80100a52: 75 2b jne 80100a7f +} +80100a54: 8d 65 f4 lea -0xc(%ebp),%esp +80100a57: 5b pop %ebx +80100a58: 5e pop %esi +80100a59: 5f pop %edi +80100a5a: 5d pop %ebp +80100a5b: c3 ret + if (c != 0 && input->e - input->r < INPUT_BUF) { +80100a5c: 85 db test %ebx,%ebx +80100a5e: 0f 84 b3 fe ff ff je 80100917 +80100a64: e9 ce fe ff ff jmp 80100937 +80100a69: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80100a70: b8 00 01 00 00 mov $0x100,%eax +80100a75: e8 96 f9 ff ff call 80100410 +80100a7a: e9 98 fe ff ff jmp 80100917 +} +80100a7f: 8d 65 f4 lea -0xc(%ebp),%esp +80100a82: 5b pop %ebx +80100a83: 5e pop %esi +80100a84: 5f pop %edi +80100a85: 5d pop %ebp + procdump(); // now call procdump() wo. cons.lock held +80100a86: e9 b5 38 00 00 jmp 80104340 + input->buf[input->e++ % INPUT_BUF] = c; +80100a8b: c6 04 02 0a movb $0xa,(%edx,%eax,1) + if (panicked) { +80100a8f: 8b 45 e4 mov -0x1c(%ebp),%eax +80100a92: 85 c0 test %eax,%eax +80100a94: 74 0a je 80100aa0 +80100a96: fa cli + for (;;) { +80100a97: eb fe jmp 80100a97 +80100a99: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80100aa0: b8 0a 00 00 00 mov $0xa,%eax +80100aa5: e8 66 f9 ff ff call 80100410 + input->w = input->e; +80100aaa: a1 80 ee 10 80 mov 0x8010ee80,%eax +80100aaf: 8b 90 88 00 00 00 mov 0x88(%eax),%edx +80100ab5: 89 90 84 00 00 00 mov %edx,0x84(%eax) + wakeup(&(input->r)); +80100abb: 83 ec 0c sub $0xc,%esp +80100abe: 83 e8 80 sub $0xffffff80,%eax +80100ac1: 50 push %eax +80100ac2: e8 99 37 00 00 call 80104260 +80100ac7: 83 c4 10 add $0x10,%esp +80100aca: e9 48 fe ff ff jmp 80100917 +80100acf: 90 nop + +80100ad0 : + +void consoleinit(void) { +80100ad0: 55 push %ebp +80100ad1: 89 e5 mov %esp,%ebp +80100ad3: 83 ec 10 sub $0x10,%esp + initlock(&cons.lock, "console"); +80100ad6: 68 48 74 10 80 push $0x80107448 +80100adb: 68 40 ef 10 80 push $0x8010ef40 +80100ae0: e8 4b 3a 00 00 call 80104530 + + devsw[CONSOLE].write = consolewrite; + devsw[CONSOLE].read = consoleread; + cons.locking = 1; + + ioapicenable(IRQ_KBD, 0); +80100ae5: 58 pop %eax +80100ae6: 5a pop %edx +80100ae7: 6a 00 push $0x0 +80100ae9: 6a 01 push $0x1 + input = &inputBuffer; +80100aeb: c7 05 80 ee 10 80 a0 movl $0x8010eea0,0x8010ee80 +80100af2: ee 10 80 + devsw[CONSOLE].write = consolewrite; +80100af5: c7 05 2c f9 10 80 a0 movl $0x801005a0,0x8010f92c +80100afc: 05 10 80 + devsw[CONSOLE].read = consoleread; +80100aff: c7 05 28 f9 10 80 80 movl $0x80100280,0x8010f928 +80100b06: 02 10 80 + cons.locking = 1; +80100b09: c7 05 74 ef 10 80 01 movl $0x1,0x8010ef74 +80100b10: 00 00 00 + ioapicenable(IRQ_KBD, 0); +80100b13: e8 88 1a 00 00 call 801025a0 +} +80100b18: 83 c4 10 add $0x10,%esp +80100b1b: c9 leave +80100b1c: c3 ret +80100b1d: 66 90 xchg %ax,%ax +80100b1f: 90 nop + +80100b20 : +#include "proc.h" +#include "defs.h" +#include "x86.h" +#include "elf.h" + +void cleanupexec(pde_t * pgdir, struct inode *ip) { +80100b20: 55 push %ebp +80100b21: 89 e5 mov %esp,%ebp +80100b23: 53 push %ebx +80100b24: 83 ec 04 sub $0x4,%esp +80100b27: 8b 45 08 mov 0x8(%ebp),%eax +80100b2a: 8b 5d 0c mov 0xc(%ebp),%ebx + if (pgdir) { +80100b2d: 85 c0 test %eax,%eax +80100b2f: 74 0c je 80100b3d + freevm(pgdir); +80100b31: 83 ec 0c sub $0xc,%esp +80100b34: 50 push %eax +80100b35: e8 a6 64 00 00 call 80106fe0 +80100b3a: 83 c4 10 add $0x10,%esp + } + if (ip) { +80100b3d: 85 db test %ebx,%ebx +80100b3f: 74 1f je 80100b60 + iunlockput(ip); +80100b41: 83 ec 0c sub $0xc,%esp +80100b44: 53 push %ebx +80100b45: e8 e6 0f 00 00 call 80101b30 + end_op(); + } +} +80100b4a: 8b 5d fc mov -0x4(%ebp),%ebx + end_op(); +80100b4d: 83 c4 10 add $0x10,%esp +} +80100b50: c9 leave + end_op(); +80100b51: e9 9a 23 00 00 jmp 80102ef0 +80100b56: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80100b5d: 8d 76 00 lea 0x0(%esi),%esi +} +80100b60: 8b 5d fc mov -0x4(%ebp),%ebx +80100b63: c9 leave +80100b64: c3 ret +80100b65: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80100b6c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80100b70 : + +int exec(char *path, char **argv) { +80100b70: 55 push %ebp +80100b71: 89 e5 mov %esp,%ebp +80100b73: 57 push %edi +80100b74: 56 push %esi +80100b75: 53 push %ebx +80100b76: 81 ec 0c 01 00 00 sub $0x10c,%esp + uint argc, sz, sp, ustack[3 + MAXARG + 1]; + struct elfhdr elf; + struct inode *ip; + struct proghdr ph; + pde_t *pgdir, *oldpgdir; + struct proc *curproc = myproc(); +80100b7c: e8 4f 2f 00 00 call 80103ad0 +80100b81: 89 85 ec fe ff ff mov %eax,-0x114(%ebp) + + begin_op(); +80100b87: e8 f4 22 00 00 call 80102e80 + + if ((ip = namei(path)) == 0) { +80100b8c: 83 ec 0c sub $0xc,%esp +80100b8f: ff 75 08 push 0x8(%ebp) +80100b92: e8 29 16 00 00 call 801021c0 +80100b97: 83 c4 10 add $0x10,%esp +80100b9a: 85 c0 test %eax,%eax +80100b9c: 0f 84 49 03 00 00 je 80100eeb + end_op(); + cprintf("exec: fail\n"); + return -1; + } + ilock(ip); +80100ba2: 83 ec 0c sub $0xc,%esp +80100ba5: 89 c7 mov %eax,%edi +80100ba7: 50 push %eax +80100ba8: e8 f3 0c 00 00 call 801018a0 + pgdir = 0; + + // Check ELF header + if (readi(ip, (char*)&elf, 0, sizeof(elf)) != sizeof(elf)) { +80100bad: 8d 85 24 ff ff ff lea -0xdc(%ebp),%eax +80100bb3: 6a 34 push $0x34 +80100bb5: 6a 00 push $0x0 +80100bb7: 50 push %eax +80100bb8: 57 push %edi +80100bb9: e8 f2 0f 00 00 call 80101bb0 +80100bbe: 83 c4 20 add $0x20,%esp +80100bc1: 83 f8 34 cmp $0x34,%eax +80100bc4: 0f 85 d6 02 00 00 jne 80100ea0 + cleanupexec(pgdir, ip); + return -1; + } + if (elf.magic != ELF_MAGIC) { +80100bca: 81 bd 24 ff ff ff 7f cmpl $0x464c457f,-0xdc(%ebp) +80100bd1: 45 4c 46 +80100bd4: 0f 85 c6 02 00 00 jne 80100ea0 + cleanupexec(pgdir, ip); + return -1; + } + + if ((pgdir = setupkvm()) == 0) { +80100bda: e8 81 64 00 00 call 80107060 +80100bdf: 89 85 f4 fe ff ff mov %eax,-0x10c(%ebp) +80100be5: 85 c0 test %eax,%eax +80100be7: 0f 84 b3 02 00 00 je 80100ea0 + return -1; + } + + // Load program into memory. + sz = 0; + for (i = 0, off = elf.phoff; i < elf.phnum; i++, off += sizeof(ph)) { +80100bed: 66 83 bd 50 ff ff ff cmpw $0x0,-0xb0(%ebp) +80100bf4: 00 +80100bf5: 8b 9d 40 ff ff ff mov -0xc0(%ebp),%ebx +80100bfb: 0f 84 ba 02 00 00 je 80100ebb + sz = 0; +80100c01: c7 85 f0 fe ff ff 00 movl $0x0,-0x110(%ebp) +80100c08: 00 00 00 + for (i = 0, off = elf.phoff; i < elf.phnum; i++, off += sizeof(ph)) { +80100c0b: 31 f6 xor %esi,%esi +80100c0d: e9 8c 00 00 00 jmp 80100c9e +80100c12: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) { + cleanupexec(pgdir, ip); + return -1; + } + if (ph.type != ELF_PROG_LOAD) { +80100c18: 83 bd 04 ff ff ff 01 cmpl $0x1,-0xfc(%ebp) +80100c1f: 75 6c jne 80100c8d + continue; + } + if (ph.memsz < ph.filesz) { +80100c21: 8b 85 18 ff ff ff mov -0xe8(%ebp),%eax +80100c27: 3b 85 14 ff ff ff cmp -0xec(%ebp),%eax +80100c2d: 0f 82 87 00 00 00 jb 80100cba + cleanupexec(pgdir, ip); + return -1; + } + if (ph.vaddr + ph.memsz < ph.vaddr) { +80100c33: 03 85 0c ff ff ff add -0xf4(%ebp),%eax +80100c39: 72 7f jb 80100cba + cleanupexec(pgdir, ip); + return -1; + } + if ((sz = allocuvm(pgdir, sz, ph.vaddr + ph.memsz)) == 0) { +80100c3b: 83 ec 04 sub $0x4,%esp +80100c3e: 50 push %eax +80100c3f: ff b5 f0 fe ff ff push -0x110(%ebp) +80100c45: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100c4b: e8 30 62 00 00 call 80106e80 +80100c50: 83 c4 10 add $0x10,%esp +80100c53: 89 85 f0 fe ff ff mov %eax,-0x110(%ebp) +80100c59: 85 c0 test %eax,%eax +80100c5b: 74 5d je 80100cba + cleanupexec(pgdir, ip); + return -1; + } + if (ph.vaddr % PGSIZE != 0) { +80100c5d: 8b 85 0c ff ff ff mov -0xf4(%ebp),%eax +80100c63: a9 ff 0f 00 00 test $0xfff,%eax +80100c68: 75 50 jne 80100cba + cleanupexec(pgdir, ip); + return -1; + } + if (loaduvm(pgdir, (char*)ph.vaddr, ip, ph.off, ph.filesz) < 0) { +80100c6a: 83 ec 0c sub $0xc,%esp +80100c6d: ff b5 14 ff ff ff push -0xec(%ebp) +80100c73: ff b5 08 ff ff ff push -0xf8(%ebp) +80100c79: 57 push %edi +80100c7a: 50 push %eax +80100c7b: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100c81: e8 0a 61 00 00 call 80106d90 +80100c86: 83 c4 20 add $0x20,%esp +80100c89: 85 c0 test %eax,%eax +80100c8b: 78 2d js 80100cba + for (i = 0, off = elf.phoff; i < elf.phnum; i++, off += sizeof(ph)) { +80100c8d: 0f b7 85 50 ff ff ff movzwl -0xb0(%ebp),%eax +80100c94: 83 c6 01 add $0x1,%esi +80100c97: 83 c3 20 add $0x20,%ebx +80100c9a: 39 f0 cmp %esi,%eax +80100c9c: 7e 4a jle 80100ce8 + if (readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) { +80100c9e: 8d 85 04 ff ff ff lea -0xfc(%ebp),%eax +80100ca4: 6a 20 push $0x20 +80100ca6: 53 push %ebx +80100ca7: 50 push %eax +80100ca8: 57 push %edi +80100ca9: e8 02 0f 00 00 call 80101bb0 +80100cae: 83 c4 10 add $0x10,%esp +80100cb1: 83 f8 20 cmp $0x20,%eax +80100cb4: 0f 84 5e ff ff ff je 80100c18 + freevm(pgdir); +80100cba: 83 ec 0c sub $0xc,%esp +80100cbd: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100cc3: e8 18 63 00 00 call 80106fe0 + iunlockput(ip); +80100cc8: 89 3c 24 mov %edi,(%esp) +80100ccb: e8 60 0e 00 00 call 80101b30 + end_op(); +80100cd0: e8 1b 22 00 00 call 80102ef0 +} +80100cd5: 83 c4 10 add $0x10,%esp + cleanupexec(pgdir, ip); + return -1; +80100cd8: b8 ff ff ff ff mov $0xffffffff,%eax + curproc->tf->eip = elf.entry; // main + curproc->tf->esp = sp; + switchuvm(curproc); + freevm(oldpgdir); + return 0; +} +80100cdd: 8d 65 f4 lea -0xc(%ebp),%esp +80100ce0: 5b pop %ebx +80100ce1: 5e pop %esi +80100ce2: 5f pop %edi +80100ce3: 5d pop %ebp +80100ce4: c3 ret +80100ce5: 8d 76 00 lea 0x0(%esi),%esi + sz = PGROUNDUP(sz); +80100ce8: 8b b5 f0 fe ff ff mov -0x110(%ebp),%esi +80100cee: 81 c6 ff 0f 00 00 add $0xfff,%esi +80100cf4: 81 e6 00 f0 ff ff and $0xfffff000,%esi + if ((sz = allocuvm(pgdir, sz, sz + 2 * PGSIZE)) == 0) { +80100cfa: 8d 9e 00 20 00 00 lea 0x2000(%esi),%ebx + iunlockput(ip); +80100d00: 83 ec 0c sub $0xc,%esp +80100d03: 57 push %edi +80100d04: e8 27 0e 00 00 call 80101b30 + end_op(); +80100d09: e8 e2 21 00 00 call 80102ef0 + if ((sz = allocuvm(pgdir, sz, sz + 2 * PGSIZE)) == 0) { +80100d0e: 83 c4 0c add $0xc,%esp +80100d11: 53 push %ebx +80100d12: 56 push %esi +80100d13: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100d19: e8 62 61 00 00 call 80106e80 +80100d1e: 83 c4 10 add $0x10,%esp +80100d21: 89 c7 mov %eax,%edi +80100d23: 85 c0 test %eax,%eax +80100d25: 0f 84 87 00 00 00 je 80100db2 + clearpteu(pgdir, (char*)(sz - 2 * PGSIZE)); +80100d2b: 83 ec 08 sub $0x8,%esp +80100d2e: 8d 80 00 e0 ff ff lea -0x2000(%eax),%eax + for (argc = 0; argv[argc]; argc++) { +80100d34: 89 fb mov %edi,%ebx +80100d36: 31 f6 xor %esi,%esi + clearpteu(pgdir, (char*)(sz - 2 * PGSIZE)); +80100d38: 50 push %eax +80100d39: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100d3f: e8 bc 63 00 00 call 80107100 + for (argc = 0; argv[argc]; argc++) { +80100d44: 8b 45 0c mov 0xc(%ebp),%eax +80100d47: 83 c4 10 add $0x10,%esp +80100d4a: 8b 08 mov (%eax),%ecx +80100d4c: 85 c9 test %ecx,%ecx +80100d4e: 0f 84 73 01 00 00 je 80100ec7 +80100d54: 89 bd f0 fe ff ff mov %edi,-0x110(%ebp) +80100d5a: 8b 7d 0c mov 0xc(%ebp),%edi +80100d5d: eb 1f jmp 80100d7e +80100d5f: 90 nop +80100d60: 8d 46 01 lea 0x1(%esi),%eax + ustack[3 + argc] = sp; +80100d63: 89 9c b5 64 ff ff ff mov %ebx,-0x9c(%ebp,%esi,4) +80100d6a: 8d 95 58 ff ff ff lea -0xa8(%ebp),%edx + for (argc = 0; argv[argc]; argc++) { +80100d70: 8b 0c 87 mov (%edi,%eax,4),%ecx +80100d73: 85 c9 test %ecx,%ecx +80100d75: 74 59 je 80100dd0 + if (argc >= MAXARG) { +80100d77: 83 f8 20 cmp $0x20,%eax +80100d7a: 74 36 je 80100db2 +80100d7c: 89 c6 mov %eax,%esi + sp = (sp - (strlen(argv[argc]) + 1)) & ~3; +80100d7e: 83 ec 0c sub $0xc,%esp +80100d81: 51 push %ecx +80100d82: e8 39 3c 00 00 call 801049c0 + if (copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0) { +80100d87: 5a pop %edx +80100d88: ff 34 b7 push (%edi,%esi,4) + sp = (sp - (strlen(argv[argc]) + 1)) & ~3; +80100d8b: 29 c3 sub %eax,%ebx +80100d8d: 83 eb 01 sub $0x1,%ebx + if (copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0) { +80100d90: e8 2b 3c 00 00 call 801049c0 + sp = (sp - (strlen(argv[argc]) + 1)) & ~3; +80100d95: 83 e3 fc and $0xfffffffc,%ebx + if (copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0) { +80100d98: 83 c0 01 add $0x1,%eax +80100d9b: 50 push %eax +80100d9c: ff 34 b7 push (%edi,%esi,4) +80100d9f: 53 push %ebx +80100da0: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100da6: e8 45 65 00 00 call 801072f0 +80100dab: 83 c4 20 add $0x20,%esp +80100dae: 85 c0 test %eax,%eax +80100db0: 79 ae jns 80100d60 + freevm(pgdir); +80100db2: 83 ec 0c sub $0xc,%esp +80100db5: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100dbb: e8 20 62 00 00 call 80106fe0 +} +80100dc0: 83 c4 10 add $0x10,%esp +} +80100dc3: 8d 65 f4 lea -0xc(%ebp),%esp + return -1; +80100dc6: b8 ff ff ff ff mov $0xffffffff,%eax +} +80100dcb: 5b pop %ebx +80100dcc: 5e pop %esi +80100dcd: 5f pop %edi +80100dce: 5d pop %ebp +80100dcf: c3 ret + ustack[2] = sp - (argc + 1) * 4; // argv pointer +80100dd0: 8d 0c b5 08 00 00 00 lea 0x8(,%esi,4),%ecx + ustack[3 + argc] = 0; +80100dd7: 8b bd f0 fe ff ff mov -0x110(%ebp),%edi +80100ddd: 89 85 f0 fe ff ff mov %eax,-0x110(%ebp) +80100de3: 8d 46 04 lea 0x4(%esi),%eax + sp -= (3 + argc + 1) * 4; +80100de6: 8d 71 0c lea 0xc(%ecx),%esi + ustack[3 + argc] = 0; +80100de9: c7 84 85 58 ff ff ff movl $0x0,-0xa8(%ebp,%eax,4) +80100df0: 00 00 00 00 + ustack[1] = argc; +80100df4: 8b 85 f0 fe ff ff mov -0x110(%ebp),%eax + if (copyout(pgdir, sp, ustack, (3 + argc + 1) * 4) < 0) { +80100dfa: 56 push %esi + ustack[1] = argc; +80100dfb: 89 85 5c ff ff ff mov %eax,-0xa4(%ebp) + ustack[2] = sp - (argc + 1) * 4; // argv pointer +80100e01: 89 d8 mov %ebx,%eax + sp -= (3 + argc + 1) * 4; +80100e03: 29 f3 sub %esi,%ebx + if (copyout(pgdir, sp, ustack, (3 + argc + 1) * 4) < 0) { +80100e05: 52 push %edx + ustack[2] = sp - (argc + 1) * 4; // argv pointer +80100e06: 29 c8 sub %ecx,%eax + if (copyout(pgdir, sp, ustack, (3 + argc + 1) * 4) < 0) { +80100e08: 53 push %ebx +80100e09: ff b5 f4 fe ff ff push -0x10c(%ebp) + ustack[0] = 0xffffffff; // fake return PC +80100e0f: c7 85 58 ff ff ff ff movl $0xffffffff,-0xa8(%ebp) +80100e16: ff ff ff + ustack[2] = sp - (argc + 1) * 4; // argv pointer +80100e19: 89 85 60 ff ff ff mov %eax,-0xa0(%ebp) + if (copyout(pgdir, sp, ustack, (3 + argc + 1) * 4) < 0) { +80100e1f: e8 cc 64 00 00 call 801072f0 +80100e24: 83 c4 10 add $0x10,%esp +80100e27: 85 c0 test %eax,%eax +80100e29: 0f 88 db 00 00 00 js 80100f0a + for (last = s = path; *s; s++) { +80100e2f: 8b 45 08 mov 0x8(%ebp),%eax +80100e32: 8b 55 08 mov 0x8(%ebp),%edx +80100e35: 8b 4d 08 mov 0x8(%ebp),%ecx +80100e38: 0f b6 00 movzbl (%eax),%eax +80100e3b: 84 c0 test %al,%al +80100e3d: 74 10 je 80100e4f +80100e3f: 90 nop + last = s + 1; +80100e40: 83 c1 01 add $0x1,%ecx +80100e43: 3c 2f cmp $0x2f,%al + for (last = s = path; *s; s++) { +80100e45: 0f b6 01 movzbl (%ecx),%eax + last = s + 1; +80100e48: 0f 44 d1 cmove %ecx,%edx + for (last = s = path; *s; s++) { +80100e4b: 84 c0 test %al,%al +80100e4d: 75 f1 jne 80100e40 + safestrcpy(curproc->name, last, sizeof(curproc->name)); +80100e4f: 8b b5 ec fe ff ff mov -0x114(%ebp),%esi +80100e55: 83 ec 04 sub $0x4,%esp +80100e58: 6a 10 push $0x10 +80100e5a: 8d 46 6c lea 0x6c(%esi),%eax +80100e5d: 52 push %edx +80100e5e: 50 push %eax +80100e5f: e8 1c 3b 00 00 call 80104980 + curproc->pgdir = pgdir; +80100e64: 8b 95 f4 fe ff ff mov -0x10c(%ebp),%edx + oldpgdir = curproc->pgdir; +80100e6a: 89 f1 mov %esi,%ecx +80100e6c: 8b 76 04 mov 0x4(%esi),%esi + curproc->tf->eip = elf.entry; // main +80100e6f: 8b 41 18 mov 0x18(%ecx),%eax + curproc->sz = sz; +80100e72: 89 39 mov %edi,(%ecx) + curproc->pgdir = pgdir; +80100e74: 89 51 04 mov %edx,0x4(%ecx) + curproc->tf->eip = elf.entry; // main +80100e77: 8b 95 3c ff ff ff mov -0xc4(%ebp),%edx +80100e7d: 89 50 38 mov %edx,0x38(%eax) + curproc->tf->esp = sp; +80100e80: 8b 41 18 mov 0x18(%ecx),%eax +80100e83: 89 58 44 mov %ebx,0x44(%eax) + switchuvm(curproc); +80100e86: 89 0c 24 mov %ecx,(%esp) +80100e89: e8 72 5d 00 00 call 80106c00 + freevm(oldpgdir); +80100e8e: 89 34 24 mov %esi,(%esp) +80100e91: e8 4a 61 00 00 call 80106fe0 + return 0; +80100e96: 83 c4 10 add $0x10,%esp +80100e99: 31 c0 xor %eax,%eax +80100e9b: e9 3d fe ff ff jmp 80100cdd + iunlockput(ip); +80100ea0: 83 ec 0c sub $0xc,%esp +80100ea3: 57 push %edi +80100ea4: e8 87 0c 00 00 call 80101b30 + end_op(); +80100ea9: e8 42 20 00 00 call 80102ef0 +} +80100eae: 83 c4 10 add $0x10,%esp + return -1; +80100eb1: b8 ff ff ff ff mov $0xffffffff,%eax +} +80100eb6: e9 22 fe ff ff jmp 80100cdd + for (i = 0, off = elf.phoff; i < elf.phnum; i++, off += sizeof(ph)) { +80100ebb: bb 00 20 00 00 mov $0x2000,%ebx +80100ec0: 31 f6 xor %esi,%esi +80100ec2: e9 39 fe ff ff jmp 80100d00 + for (argc = 0; argv[argc]; argc++) { +80100ec7: be 10 00 00 00 mov $0x10,%esi +80100ecc: b9 04 00 00 00 mov $0x4,%ecx +80100ed1: b8 03 00 00 00 mov $0x3,%eax +80100ed6: c7 85 f0 fe ff ff 00 movl $0x0,-0x110(%ebp) +80100edd: 00 00 00 +80100ee0: 8d 95 58 ff ff ff lea -0xa8(%ebp),%edx +80100ee6: e9 fe fe ff ff jmp 80100de9 + end_op(); +80100eeb: e8 00 20 00 00 call 80102ef0 + cprintf("exec: fail\n"); +80100ef0: 83 ec 0c sub $0xc,%esp +80100ef3: 68 61 74 10 80 push $0x80107461 +80100ef8: e8 b3 f7 ff ff call 801006b0 + return -1; +80100efd: 83 c4 10 add $0x10,%esp +80100f00: b8 ff ff ff ff mov $0xffffffff,%eax +80100f05: e9 d3 fd ff ff jmp 80100cdd + cleanupexec(pgdir, ip); +80100f0a: 50 push %eax +80100f0b: 50 push %eax +80100f0c: 6a 00 push $0x0 +80100f0e: ff b5 f4 fe ff ff push -0x10c(%ebp) +80100f14: e8 07 fc ff ff call 80100b20 + return -1; +80100f19: 83 c4 10 add $0x10,%esp +80100f1c: 83 c8 ff or $0xffffffff,%eax +80100f1f: e9 b9 fd ff ff jmp 80100cdd +80100f24: 66 90 xchg %ax,%ax +80100f26: 66 90 xchg %ax,%ax +80100f28: 66 90 xchg %ax,%ax +80100f2a: 66 90 xchg %ax,%ax +80100f2c: 66 90 xchg %ax,%ax +80100f2e: 66 90 xchg %ax,%ax + +80100f30 : +struct { + struct spinlock lock; + struct file file[NFILE]; +} ftable; + +void fileinit(void) { +80100f30: 55 push %ebp +80100f31: 89 e5 mov %esp,%ebp +80100f33: 83 ec 10 sub $0x10,%esp + initlock(&ftable.lock, "ftable"); +80100f36: 68 6d 74 10 80 push $0x8010746d +80100f3b: 68 80 ef 10 80 push $0x8010ef80 +80100f40: e8 eb 35 00 00 call 80104530 +} +80100f45: 83 c4 10 add $0x10,%esp +80100f48: c9 leave +80100f49: c3 ret +80100f4a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80100f50 : + +// Allocate a file structure. +struct file* filealloc(void) { +80100f50: 55 push %ebp +80100f51: 89 e5 mov %esp,%ebp +80100f53: 53 push %ebx + struct file *f; + + acquire(&ftable.lock); + for (f = ftable.file; f < ftable.file + NFILE; f++) { +80100f54: bb b4 ef 10 80 mov $0x8010efb4,%ebx +struct file* filealloc(void) { +80100f59: 83 ec 10 sub $0x10,%esp + acquire(&ftable.lock); +80100f5c: 68 80 ef 10 80 push $0x8010ef80 +80100f61: e8 9a 37 00 00 call 80104700 +80100f66: 83 c4 10 add $0x10,%esp +80100f69: eb 10 jmp 80100f7b +80100f6b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80100f6f: 90 nop + for (f = ftable.file; f < ftable.file + NFILE; f++) { +80100f70: 83 c3 18 add $0x18,%ebx +80100f73: 81 fb 14 f9 10 80 cmp $0x8010f914,%ebx +80100f79: 74 25 je 80100fa0 + if (f->ref == 0) { +80100f7b: 8b 43 04 mov 0x4(%ebx),%eax +80100f7e: 85 c0 test %eax,%eax +80100f80: 75 ee jne 80100f70 + f->ref = 1; + release(&ftable.lock); +80100f82: 83 ec 0c sub $0xc,%esp + f->ref = 1; +80100f85: c7 43 04 01 00 00 00 movl $0x1,0x4(%ebx) + release(&ftable.lock); +80100f8c: 68 80 ef 10 80 push $0x8010ef80 +80100f91: e8 0a 37 00 00 call 801046a0 + return f; + } + } + release(&ftable.lock); + return 0; +} +80100f96: 89 d8 mov %ebx,%eax + return f; +80100f98: 83 c4 10 add $0x10,%esp +} +80100f9b: 8b 5d fc mov -0x4(%ebp),%ebx +80100f9e: c9 leave +80100f9f: c3 ret + release(&ftable.lock); +80100fa0: 83 ec 0c sub $0xc,%esp + return 0; +80100fa3: 31 db xor %ebx,%ebx + release(&ftable.lock); +80100fa5: 68 80 ef 10 80 push $0x8010ef80 +80100faa: e8 f1 36 00 00 call 801046a0 +} +80100faf: 89 d8 mov %ebx,%eax + return 0; +80100fb1: 83 c4 10 add $0x10,%esp +} +80100fb4: 8b 5d fc mov -0x4(%ebp),%ebx +80100fb7: c9 leave +80100fb8: c3 ret +80100fb9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80100fc0 : + +// Increment ref count for file f. +struct file* filedup(struct file *f) { +80100fc0: 55 push %ebp +80100fc1: 89 e5 mov %esp,%ebp +80100fc3: 53 push %ebx +80100fc4: 83 ec 10 sub $0x10,%esp +80100fc7: 8b 5d 08 mov 0x8(%ebp),%ebx + acquire(&ftable.lock); +80100fca: 68 80 ef 10 80 push $0x8010ef80 +80100fcf: e8 2c 37 00 00 call 80104700 + if (f->ref < 1) { +80100fd4: 8b 43 04 mov 0x4(%ebx),%eax +80100fd7: 83 c4 10 add $0x10,%esp +80100fda: 85 c0 test %eax,%eax +80100fdc: 7e 1a jle 80100ff8 + panic("filedup"); + } + f->ref++; +80100fde: 83 c0 01 add $0x1,%eax + release(&ftable.lock); +80100fe1: 83 ec 0c sub $0xc,%esp + f->ref++; +80100fe4: 89 43 04 mov %eax,0x4(%ebx) + release(&ftable.lock); +80100fe7: 68 80 ef 10 80 push $0x8010ef80 +80100fec: e8 af 36 00 00 call 801046a0 + return f; +} +80100ff1: 89 d8 mov %ebx,%eax +80100ff3: 8b 5d fc mov -0x4(%ebp),%ebx +80100ff6: c9 leave +80100ff7: c3 ret + panic("filedup"); +80100ff8: 83 ec 0c sub $0xc,%esp +80100ffb: 68 74 74 10 80 push $0x80107474 +80101000: e8 8b f3 ff ff call 80100390 +80101005: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010100c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80101010 : + +// Close file f. (Decrement ref count, close when reaches 0.) +void fileclose(struct file *f) { +80101010: 55 push %ebp +80101011: 89 e5 mov %esp,%ebp +80101013: 57 push %edi +80101014: 56 push %esi +80101015: 53 push %ebx +80101016: 83 ec 28 sub $0x28,%esp +80101019: 8b 5d 08 mov 0x8(%ebp),%ebx + struct file ff; + + acquire(&ftable.lock); +8010101c: 68 80 ef 10 80 push $0x8010ef80 +80101021: e8 da 36 00 00 call 80104700 + if (f->ref < 1) { +80101026: 8b 53 04 mov 0x4(%ebx),%edx +80101029: 83 c4 10 add $0x10,%esp +8010102c: 85 d2 test %edx,%edx +8010102e: 0f 8e a5 00 00 00 jle 801010d9 + panic("fileclose"); + } + if (--f->ref > 0) { +80101034: 83 ea 01 sub $0x1,%edx +80101037: 89 53 04 mov %edx,0x4(%ebx) +8010103a: 75 44 jne 80101080 + release(&ftable.lock); + return; + } + ff = *f; +8010103c: 0f b6 43 09 movzbl 0x9(%ebx),%eax + f->ref = 0; + f->type = FD_NONE; + release(&ftable.lock); +80101040: 83 ec 0c sub $0xc,%esp + ff = *f; +80101043: 8b 3b mov (%ebx),%edi + f->type = FD_NONE; +80101045: c7 03 00 00 00 00 movl $0x0,(%ebx) + ff = *f; +8010104b: 8b 73 0c mov 0xc(%ebx),%esi +8010104e: 88 45 e7 mov %al,-0x19(%ebp) +80101051: 8b 43 10 mov 0x10(%ebx),%eax + release(&ftable.lock); +80101054: 68 80 ef 10 80 push $0x8010ef80 + ff = *f; +80101059: 89 45 e0 mov %eax,-0x20(%ebp) + release(&ftable.lock); +8010105c: e8 3f 36 00 00 call 801046a0 + + if (ff.type == FD_PIPE) { +80101061: 83 c4 10 add $0x10,%esp +80101064: 83 ff 01 cmp $0x1,%edi +80101067: 74 57 je 801010c0 + pipeclose(ff.pipe, ff.writable); + } + else if (ff.type == FD_INODE) { +80101069: 83 ff 02 cmp $0x2,%edi +8010106c: 74 2a je 80101098 + begin_op(); + iput(ff.ip); + end_op(); + } +} +8010106e: 8d 65 f4 lea -0xc(%ebp),%esp +80101071: 5b pop %ebx +80101072: 5e pop %esi +80101073: 5f pop %edi +80101074: 5d pop %ebp +80101075: c3 ret +80101076: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010107d: 8d 76 00 lea 0x0(%esi),%esi + release(&ftable.lock); +80101080: c7 45 08 80 ef 10 80 movl $0x8010ef80,0x8(%ebp) +} +80101087: 8d 65 f4 lea -0xc(%ebp),%esp +8010108a: 5b pop %ebx +8010108b: 5e pop %esi +8010108c: 5f pop %edi +8010108d: 5d pop %ebp + release(&ftable.lock); +8010108e: e9 0d 36 00 00 jmp 801046a0 +80101093: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80101097: 90 nop + begin_op(); +80101098: e8 e3 1d 00 00 call 80102e80 + iput(ff.ip); +8010109d: 83 ec 0c sub $0xc,%esp +801010a0: ff 75 e0 push -0x20(%ebp) +801010a3: e8 28 09 00 00 call 801019d0 + end_op(); +801010a8: 83 c4 10 add $0x10,%esp +} +801010ab: 8d 65 f4 lea -0xc(%ebp),%esp +801010ae: 5b pop %ebx +801010af: 5e pop %esi +801010b0: 5f pop %edi +801010b1: 5d pop %ebp + end_op(); +801010b2: e9 39 1e 00 00 jmp 80102ef0 +801010b7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801010be: 66 90 xchg %ax,%ax + pipeclose(ff.pipe, ff.writable); +801010c0: 0f be 5d e7 movsbl -0x19(%ebp),%ebx +801010c4: 83 ec 08 sub $0x8,%esp +801010c7: 53 push %ebx +801010c8: 56 push %esi +801010c9: e8 c2 25 00 00 call 80103690 +801010ce: 83 c4 10 add $0x10,%esp +} +801010d1: 8d 65 f4 lea -0xc(%ebp),%esp +801010d4: 5b pop %ebx +801010d5: 5e pop %esi +801010d6: 5f pop %edi +801010d7: 5d pop %ebp +801010d8: c3 ret + panic("fileclose"); +801010d9: 83 ec 0c sub $0xc,%esp +801010dc: 68 7c 74 10 80 push $0x8010747c +801010e1: e8 aa f2 ff ff call 80100390 +801010e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801010ed: 8d 76 00 lea 0x0(%esi),%esi + +801010f0 : + +// Get metadata about file f. +int filestat(struct file *f, struct stat *st) { +801010f0: 55 push %ebp +801010f1: 89 e5 mov %esp,%ebp +801010f3: 53 push %ebx +801010f4: 83 ec 04 sub $0x4,%esp +801010f7: 8b 5d 08 mov 0x8(%ebp),%ebx + if (f->type == FD_INODE) { +801010fa: 83 3b 02 cmpl $0x2,(%ebx) +801010fd: 75 31 jne 80101130 + ilock(f->ip); +801010ff: 83 ec 0c sub $0xc,%esp +80101102: ff 73 10 push 0x10(%ebx) +80101105: e8 96 07 00 00 call 801018a0 + stati(f->ip, st); +8010110a: 58 pop %eax +8010110b: 5a pop %edx +8010110c: ff 75 0c push 0xc(%ebp) +8010110f: ff 73 10 push 0x10(%ebx) +80101112: e8 69 0a 00 00 call 80101b80 + iunlock(f->ip); +80101117: 59 pop %ecx +80101118: ff 73 10 push 0x10(%ebx) +8010111b: e8 60 08 00 00 call 80101980 + return 0; + } + return -1; +} +80101120: 8b 5d fc mov -0x4(%ebp),%ebx + return 0; +80101123: 83 c4 10 add $0x10,%esp +80101126: 31 c0 xor %eax,%eax +} +80101128: c9 leave +80101129: c3 ret +8010112a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi +80101130: 8b 5d fc mov -0x4(%ebp),%ebx + return -1; +80101133: b8 ff ff ff ff mov $0xffffffff,%eax +} +80101138: c9 leave +80101139: c3 ret +8010113a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80101140 : + +// Read from file f. +int fileread(struct file *f, char *addr, int n) { +80101140: 55 push %ebp +80101141: 89 e5 mov %esp,%ebp +80101143: 57 push %edi +80101144: 56 push %esi +80101145: 53 push %ebx +80101146: 83 ec 0c sub $0xc,%esp +80101149: 8b 5d 08 mov 0x8(%ebp),%ebx +8010114c: 8b 75 0c mov 0xc(%ebp),%esi +8010114f: 8b 7d 10 mov 0x10(%ebp),%edi + int r; + + if (f->readable == 0) { +80101152: 80 7b 08 00 cmpb $0x0,0x8(%ebx) +80101156: 74 60 je 801011b8 + return -1; + } + if (f->type == FD_PIPE) { +80101158: 8b 03 mov (%ebx),%eax +8010115a: 83 f8 01 cmp $0x1,%eax +8010115d: 74 41 je 801011a0 + return piperead(f->pipe, addr, n); + } + if (f->type == FD_INODE) { +8010115f: 83 f8 02 cmp $0x2,%eax +80101162: 75 5b jne 801011bf + ilock(f->ip); +80101164: 83 ec 0c sub $0xc,%esp +80101167: ff 73 10 push 0x10(%ebx) +8010116a: e8 31 07 00 00 call 801018a0 + if ((r = readi(f->ip, addr, f->off, n)) > 0) { +8010116f: 57 push %edi +80101170: ff 73 14 push 0x14(%ebx) +80101173: 56 push %esi +80101174: ff 73 10 push 0x10(%ebx) +80101177: e8 34 0a 00 00 call 80101bb0 +8010117c: 83 c4 20 add $0x20,%esp +8010117f: 89 c6 mov %eax,%esi +80101181: 85 c0 test %eax,%eax +80101183: 7e 03 jle 80101188 + f->off += r; +80101185: 01 43 14 add %eax,0x14(%ebx) + } + iunlock(f->ip); +80101188: 83 ec 0c sub $0xc,%esp +8010118b: ff 73 10 push 0x10(%ebx) +8010118e: e8 ed 07 00 00 call 80101980 + return r; +80101193: 83 c4 10 add $0x10,%esp + } + panic("fileread"); +} +80101196: 8d 65 f4 lea -0xc(%ebp),%esp +80101199: 89 f0 mov %esi,%eax +8010119b: 5b pop %ebx +8010119c: 5e pop %esi +8010119d: 5f pop %edi +8010119e: 5d pop %ebp +8010119f: c3 ret + return piperead(f->pipe, addr, n); +801011a0: 8b 43 0c mov 0xc(%ebx),%eax +801011a3: 89 45 08 mov %eax,0x8(%ebp) +} +801011a6: 8d 65 f4 lea -0xc(%ebp),%esp +801011a9: 5b pop %ebx +801011aa: 5e pop %esi +801011ab: 5f pop %edi +801011ac: 5d pop %ebp + return piperead(f->pipe, addr, n); +801011ad: e9 7e 26 00 00 jmp 80103830 +801011b2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + return -1; +801011b8: be ff ff ff ff mov $0xffffffff,%esi +801011bd: eb d7 jmp 80101196 + panic("fileread"); +801011bf: 83 ec 0c sub $0xc,%esp +801011c2: 68 86 74 10 80 push $0x80107486 +801011c7: e8 c4 f1 ff ff call 80100390 +801011cc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +801011d0 : + + +// Write to file f. +int filewrite(struct file *f, char *addr, int n) { +801011d0: 55 push %ebp +801011d1: 89 e5 mov %esp,%ebp +801011d3: 57 push %edi +801011d4: 56 push %esi +801011d5: 53 push %ebx +801011d6: 83 ec 1c sub $0x1c,%esp +801011d9: 8b 45 0c mov 0xc(%ebp),%eax +801011dc: 8b 5d 08 mov 0x8(%ebp),%ebx +801011df: 89 45 dc mov %eax,-0x24(%ebp) +801011e2: 8b 45 10 mov 0x10(%ebp),%eax + int r; + + if (f->writable == 0) { +801011e5: 80 7b 09 00 cmpb $0x0,0x9(%ebx) +int filewrite(struct file *f, char *addr, int n) { +801011e9: 89 45 e4 mov %eax,-0x1c(%ebp) + if (f->writable == 0) { +801011ec: 0f 84 bd 00 00 00 je 801012af + return -1; + } + if (f->type == FD_PIPE) { +801011f2: 8b 03 mov (%ebx),%eax +801011f4: 83 f8 01 cmp $0x1,%eax +801011f7: 0f 84 bf 00 00 00 je 801012bc + return pipewrite(f->pipe, addr, n); + } + if (f->type == FD_INODE) { +801011fd: 83 f8 02 cmp $0x2,%eax +80101200: 0f 85 c8 00 00 00 jne 801012ce + // and 2 blocks of slop for non-aligned writes. + // this really belongs lower down, since writei() + // might be writing a device like the console. + int max = ((MAXOPBLOCKS - 1 - 1 - 2) / 2) * 512; + int i = 0; + while (i < n) { +80101206: 8b 45 e4 mov -0x1c(%ebp),%eax + int i = 0; +80101209: 31 f6 xor %esi,%esi + while (i < n) { +8010120b: 85 c0 test %eax,%eax +8010120d: 7f 30 jg 8010123f +8010120f: e9 94 00 00 00 jmp 801012a8 +80101214: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + } + + begin_op(); + ilock(f->ip); + if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) { + f->off += r; +80101218: 01 43 14 add %eax,0x14(%ebx) + } + iunlock(f->ip); +8010121b: 83 ec 0c sub $0xc,%esp +8010121e: ff 73 10 push 0x10(%ebx) + f->off += r; +80101221: 89 45 e0 mov %eax,-0x20(%ebp) + iunlock(f->ip); +80101224: e8 57 07 00 00 call 80101980 + end_op(); +80101229: e8 c2 1c 00 00 call 80102ef0 + + if (r < 0) { + break; + } + if (r != n1) { +8010122e: 8b 45 e0 mov -0x20(%ebp),%eax +80101231: 83 c4 10 add $0x10,%esp +80101234: 39 c7 cmp %eax,%edi +80101236: 75 5c jne 80101294 + panic("short filewrite"); + } + i += r; +80101238: 01 fe add %edi,%esi + while (i < n) { +8010123a: 39 75 e4 cmp %esi,-0x1c(%ebp) +8010123d: 7e 69 jle 801012a8 + int n1 = n - i; +8010123f: 8b 7d e4 mov -0x1c(%ebp),%edi +80101242: b8 00 06 00 00 mov $0x600,%eax +80101247: 29 f7 sub %esi,%edi +80101249: 39 c7 cmp %eax,%edi +8010124b: 0f 4f f8 cmovg %eax,%edi + begin_op(); +8010124e: e8 2d 1c 00 00 call 80102e80 + ilock(f->ip); +80101253: 83 ec 0c sub $0xc,%esp +80101256: ff 73 10 push 0x10(%ebx) +80101259: e8 42 06 00 00 call 801018a0 + if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) { +8010125e: 8b 45 dc mov -0x24(%ebp),%eax +80101261: 57 push %edi +80101262: ff 73 14 push 0x14(%ebx) +80101265: 01 f0 add %esi,%eax +80101267: 50 push %eax +80101268: ff 73 10 push 0x10(%ebx) +8010126b: e8 40 0a 00 00 call 80101cb0 +80101270: 83 c4 20 add $0x20,%esp +80101273: 85 c0 test %eax,%eax +80101275: 7f a1 jg 80101218 + iunlock(f->ip); +80101277: 83 ec 0c sub $0xc,%esp +8010127a: ff 73 10 push 0x10(%ebx) +8010127d: 89 45 e4 mov %eax,-0x1c(%ebp) +80101280: e8 fb 06 00 00 call 80101980 + end_op(); +80101285: e8 66 1c 00 00 call 80102ef0 + if (r < 0) { +8010128a: 8b 45 e4 mov -0x1c(%ebp),%eax +8010128d: 83 c4 10 add $0x10,%esp +80101290: 85 c0 test %eax,%eax +80101292: 75 1b jne 801012af + panic("short filewrite"); +80101294: 83 ec 0c sub $0xc,%esp +80101297: 68 8f 74 10 80 push $0x8010748f +8010129c: e8 ef f0 ff ff call 80100390 +801012a1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + } + return i == n ? n : -1; +801012a8: 89 f0 mov %esi,%eax +801012aa: 3b 75 e4 cmp -0x1c(%ebp),%esi +801012ad: 74 05 je 801012b4 +801012af: b8 ff ff ff ff mov $0xffffffff,%eax + } + panic("filewrite"); +} +801012b4: 8d 65 f4 lea -0xc(%ebp),%esp +801012b7: 5b pop %ebx +801012b8: 5e pop %esi +801012b9: 5f pop %edi +801012ba: 5d pop %ebp +801012bb: c3 ret + return pipewrite(f->pipe, addr, n); +801012bc: 8b 43 0c mov 0xc(%ebx),%eax +801012bf: 89 45 08 mov %eax,0x8(%ebp) +} +801012c2: 8d 65 f4 lea -0xc(%ebp),%esp +801012c5: 5b pop %ebx +801012c6: 5e pop %esi +801012c7: 5f pop %edi +801012c8: 5d pop %ebp + return pipewrite(f->pipe, addr, n); +801012c9: e9 62 24 00 00 jmp 80103730 + panic("filewrite"); +801012ce: 83 ec 0c sub $0xc,%esp +801012d1: 68 95 74 10 80 push $0x80107495 +801012d6: e8 b5 f0 ff ff call 80100390 +801012db: 66 90 xchg %ax,%ax +801012dd: 66 90 xchg %ax,%ax +801012df: 90 nop + +801012e0 : + } + panic("balloc: out of blocks"); +} + +// Free a disk block. +static void bfree(int dev, uint b) { +801012e0: 55 push %ebp +801012e1: 89 c1 mov %eax,%ecx + struct buf *bp; + int bi, m; + + bp = bread(dev, BBLOCK(b, sb)); +801012e3: 89 d0 mov %edx,%eax +801012e5: c1 e8 0c shr $0xc,%eax +801012e8: 03 05 ec 15 11 80 add 0x801115ec,%eax +static void bfree(int dev, uint b) { +801012ee: 89 e5 mov %esp,%ebp +801012f0: 56 push %esi +801012f1: 53 push %ebx +801012f2: 89 d3 mov %edx,%ebx + bp = bread(dev, BBLOCK(b, sb)); +801012f4: 83 ec 08 sub $0x8,%esp +801012f7: 50 push %eax +801012f8: 51 push %ecx +801012f9: e8 d2 ed ff ff call 801000d0 + bi = b % BPB; + m = 1 << (bi % 8); +801012fe: 89 d9 mov %ebx,%ecx + if ((bp->data[bi / 8] & m) == 0) { +80101300: c1 fb 03 sar $0x3,%ebx +80101303: 83 c4 10 add $0x10,%esp + bp = bread(dev, BBLOCK(b, sb)); +80101306: 89 c6 mov %eax,%esi + m = 1 << (bi % 8); +80101308: 83 e1 07 and $0x7,%ecx +8010130b: b8 01 00 00 00 mov $0x1,%eax + if ((bp->data[bi / 8] & m) == 0) { +80101310: 81 e3 ff 01 00 00 and $0x1ff,%ebx + m = 1 << (bi % 8); +80101316: d3 e0 shl %cl,%eax + if ((bp->data[bi / 8] & m) == 0) { +80101318: 0f b6 4c 1e 5c movzbl 0x5c(%esi,%ebx,1),%ecx +8010131d: 85 c1 test %eax,%ecx +8010131f: 74 23 je 80101344 + panic("freeing free block"); + } + bp->data[bi / 8] &= ~m; +80101321: f7 d0 not %eax + log_write(bp); +80101323: 83 ec 0c sub $0xc,%esp + bp->data[bi / 8] &= ~m; +80101326: 21 c8 and %ecx,%eax +80101328: 88 44 1e 5c mov %al,0x5c(%esi,%ebx,1) + log_write(bp); +8010132c: 56 push %esi +8010132d: e8 2e 1d 00 00 call 80103060 + brelse(bp); +80101332: 89 34 24 mov %esi,(%esp) +80101335: e8 b6 ee ff ff call 801001f0 +} +8010133a: 83 c4 10 add $0x10,%esp +8010133d: 8d 65 f8 lea -0x8(%ebp),%esp +80101340: 5b pop %ebx +80101341: 5e pop %esi +80101342: 5d pop %ebp +80101343: c3 ret + panic("freeing free block"); +80101344: 83 ec 0c sub $0xc,%esp +80101347: 68 9f 74 10 80 push $0x8010749f +8010134c: e8 3f f0 ff ff call 80100390 +80101351: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80101358: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010135f: 90 nop + +80101360 : +static uint balloc(uint dev) { +80101360: 55 push %ebp +80101361: 89 e5 mov %esp,%ebp +80101363: 57 push %edi +80101364: 56 push %esi +80101365: 53 push %ebx +80101366: 83 ec 1c sub $0x1c,%esp + for (b = 0; b < sb.size; b += BPB) { +80101369: 8b 0d d4 15 11 80 mov 0x801115d4,%ecx +static uint balloc(uint dev) { +8010136f: 89 45 d8 mov %eax,-0x28(%ebp) + for (b = 0; b < sb.size; b += BPB) { +80101372: 85 c9 test %ecx,%ecx +80101374: 0f 84 87 00 00 00 je 80101401 +8010137a: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + bp = bread(dev, BBLOCK(b, sb)); +80101381: 8b 75 dc mov -0x24(%ebp),%esi +80101384: 83 ec 08 sub $0x8,%esp +80101387: 89 f0 mov %esi,%eax +80101389: c1 f8 0c sar $0xc,%eax +8010138c: 03 05 ec 15 11 80 add 0x801115ec,%eax +80101392: 50 push %eax +80101393: ff 75 d8 push -0x28(%ebp) +80101396: e8 35 ed ff ff call 801000d0 +8010139b: 83 c4 10 add $0x10,%esp +8010139e: 89 45 e4 mov %eax,-0x1c(%ebp) + for (bi = 0; bi < BPB && b + bi < sb.size; bi++) { +801013a1: a1 d4 15 11 80 mov 0x801115d4,%eax +801013a6: 89 45 e0 mov %eax,-0x20(%ebp) +801013a9: 31 c0 xor %eax,%eax +801013ab: eb 2f jmp 801013dc +801013ad: 8d 76 00 lea 0x0(%esi),%esi + m = 1 << (bi % 8); +801013b0: 89 c1 mov %eax,%ecx +801013b2: bb 01 00 00 00 mov $0x1,%ebx + if ((bp->data[bi / 8] & m) == 0) { // Is block free? +801013b7: 8b 55 e4 mov -0x1c(%ebp),%edx + m = 1 << (bi % 8); +801013ba: 83 e1 07 and $0x7,%ecx +801013bd: d3 e3 shl %cl,%ebx + if ((bp->data[bi / 8] & m) == 0) { // Is block free? +801013bf: 89 c1 mov %eax,%ecx +801013c1: c1 f9 03 sar $0x3,%ecx +801013c4: 0f b6 7c 0a 5c movzbl 0x5c(%edx,%ecx,1),%edi +801013c9: 89 fa mov %edi,%edx +801013cb: 85 df test %ebx,%edi +801013cd: 74 41 je 80101410 + for (bi = 0; bi < BPB && b + bi < sb.size; bi++) { +801013cf: 83 c0 01 add $0x1,%eax +801013d2: 83 c6 01 add $0x1,%esi +801013d5: 3d 00 10 00 00 cmp $0x1000,%eax +801013da: 74 05 je 801013e1 +801013dc: 39 75 e0 cmp %esi,-0x20(%ebp) +801013df: 77 cf ja 801013b0 + brelse(bp); +801013e1: 83 ec 0c sub $0xc,%esp +801013e4: ff 75 e4 push -0x1c(%ebp) +801013e7: e8 04 ee ff ff call 801001f0 + for (b = 0; b < sb.size; b += BPB) { +801013ec: 81 45 dc 00 10 00 00 addl $0x1000,-0x24(%ebp) +801013f3: 83 c4 10 add $0x10,%esp +801013f6: 8b 45 dc mov -0x24(%ebp),%eax +801013f9: 39 05 d4 15 11 80 cmp %eax,0x801115d4 +801013ff: 77 80 ja 80101381 + panic("balloc: out of blocks"); +80101401: 83 ec 0c sub $0xc,%esp +80101404: 68 b2 74 10 80 push $0x801074b2 +80101409: e8 82 ef ff ff call 80100390 +8010140e: 66 90 xchg %ax,%ax + bp->data[bi / 8] |= m; // Mark block in use. +80101410: 8b 7d e4 mov -0x1c(%ebp),%edi + log_write(bp); +80101413: 83 ec 0c sub $0xc,%esp + bp->data[bi / 8] |= m; // Mark block in use. +80101416: 09 da or %ebx,%edx +80101418: 88 54 0f 5c mov %dl,0x5c(%edi,%ecx,1) + log_write(bp); +8010141c: 57 push %edi +8010141d: e8 3e 1c 00 00 call 80103060 + brelse(bp); +80101422: 89 3c 24 mov %edi,(%esp) +80101425: e8 c6 ed ff ff call 801001f0 + bp = bread(dev, bno); +8010142a: 58 pop %eax +8010142b: 5a pop %edx +8010142c: 56 push %esi +8010142d: ff 75 d8 push -0x28(%ebp) +80101430: e8 9b ec ff ff call 801000d0 + memset(bp->data, 0, BSIZE); +80101435: 83 c4 0c add $0xc,%esp + bp = bread(dev, bno); +80101438: 89 c3 mov %eax,%ebx + memset(bp->data, 0, BSIZE); +8010143a: 8d 40 5c lea 0x5c(%eax),%eax +8010143d: 68 00 02 00 00 push $0x200 +80101442: 6a 00 push $0x0 +80101444: 50 push %eax +80101445: e8 76 33 00 00 call 801047c0 + log_write(bp); +8010144a: 89 1c 24 mov %ebx,(%esp) +8010144d: e8 0e 1c 00 00 call 80103060 + brelse(bp); +80101452: 89 1c 24 mov %ebx,(%esp) +80101455: e8 96 ed ff ff call 801001f0 +} +8010145a: 8d 65 f4 lea -0xc(%ebp),%esp +8010145d: 89 f0 mov %esi,%eax +8010145f: 5b pop %ebx +80101460: 5e pop %esi +80101461: 5f pop %edi +80101462: 5d pop %ebp +80101463: c3 ret +80101464: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010146b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010146f: 90 nop + +80101470 : +} + +// Find the inode with number inum on device dev +// and return the in-memory copy. Does not lock +// the inode and does not read it from disk. +static struct inode* iget(uint dev, uint inum) { +80101470: 55 push %ebp +80101471: 89 e5 mov %esp,%ebp +80101473: 57 push %edi +80101474: 89 c7 mov %eax,%edi +80101476: 56 push %esi + struct inode *ip, *empty; + + acquire(&icache.lock); + + // Is the inode already cached? + empty = 0; +80101477: 31 f6 xor %esi,%esi +static struct inode* iget(uint dev, uint inum) { +80101479: 53 push %ebx + for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { +8010147a: bb b4 f9 10 80 mov $0x8010f9b4,%ebx +static struct inode* iget(uint dev, uint inum) { +8010147f: 83 ec 28 sub $0x28,%esp +80101482: 89 55 e4 mov %edx,-0x1c(%ebp) + acquire(&icache.lock); +80101485: 68 80 f9 10 80 push $0x8010f980 +8010148a: e8 71 32 00 00 call 80104700 + for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { +8010148f: 8b 55 e4 mov -0x1c(%ebp),%edx + acquire(&icache.lock); +80101492: 83 c4 10 add $0x10,%esp +80101495: eb 1b jmp 801014b2 +80101497: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010149e: 66 90 xchg %ax,%ax + if (ip->ref > 0 && ip->dev == dev && ip->inum == inum) { +801014a0: 39 3b cmp %edi,(%ebx) +801014a2: 74 6c je 80101510 + for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { +801014a4: 81 c3 90 00 00 00 add $0x90,%ebx +801014aa: 81 fb d4 15 11 80 cmp $0x801115d4,%ebx +801014b0: 73 26 jae 801014d8 + if (ip->ref > 0 && ip->dev == dev && ip->inum == inum) { +801014b2: 8b 43 08 mov 0x8(%ebx),%eax +801014b5: 85 c0 test %eax,%eax +801014b7: 7f e7 jg 801014a0 + ip->ref++; + release(&icache.lock); + return ip; + } + if (empty == 0 && ip->ref == 0) { // Remember empty slot. +801014b9: 85 f6 test %esi,%esi +801014bb: 75 e7 jne 801014a4 +801014bd: 85 c0 test %eax,%eax +801014bf: 75 76 jne 80101537 +801014c1: 89 de mov %ebx,%esi + for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { +801014c3: 81 c3 90 00 00 00 add $0x90,%ebx +801014c9: 81 fb d4 15 11 80 cmp $0x801115d4,%ebx +801014cf: 72 e1 jb 801014b2 +801014d1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + empty = ip; + } + } + + // Recycle an inode cache entry. + if (empty == 0) { +801014d8: 85 f6 test %esi,%esi +801014da: 74 79 je 80101555 + ip = empty; + ip->dev = dev; + ip->inum = inum; + ip->ref = 1; + ip->valid = 0; + release(&icache.lock); +801014dc: 83 ec 0c sub $0xc,%esp + ip->dev = dev; +801014df: 89 3e mov %edi,(%esi) + ip->inum = inum; +801014e1: 89 56 04 mov %edx,0x4(%esi) + ip->ref = 1; +801014e4: c7 46 08 01 00 00 00 movl $0x1,0x8(%esi) + ip->valid = 0; +801014eb: c7 46 4c 00 00 00 00 movl $0x0,0x4c(%esi) + release(&icache.lock); +801014f2: 68 80 f9 10 80 push $0x8010f980 +801014f7: e8 a4 31 00 00 call 801046a0 + + return ip; +801014fc: 83 c4 10 add $0x10,%esp +} +801014ff: 8d 65 f4 lea -0xc(%ebp),%esp +80101502: 89 f0 mov %esi,%eax +80101504: 5b pop %ebx +80101505: 5e pop %esi +80101506: 5f pop %edi +80101507: 5d pop %ebp +80101508: c3 ret +80101509: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + if (ip->ref > 0 && ip->dev == dev && ip->inum == inum) { +80101510: 39 53 04 cmp %edx,0x4(%ebx) +80101513: 75 8f jne 801014a4 + release(&icache.lock); +80101515: 83 ec 0c sub $0xc,%esp + ip->ref++; +80101518: 83 c0 01 add $0x1,%eax + return ip; +8010151b: 89 de mov %ebx,%esi + release(&icache.lock); +8010151d: 68 80 f9 10 80 push $0x8010f980 + ip->ref++; +80101522: 89 43 08 mov %eax,0x8(%ebx) + release(&icache.lock); +80101525: e8 76 31 00 00 call 801046a0 + return ip; +8010152a: 83 c4 10 add $0x10,%esp +} +8010152d: 8d 65 f4 lea -0xc(%ebp),%esp +80101530: 89 f0 mov %esi,%eax +80101532: 5b pop %ebx +80101533: 5e pop %esi +80101534: 5f pop %edi +80101535: 5d pop %ebp +80101536: c3 ret + for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { +80101537: 81 c3 90 00 00 00 add $0x90,%ebx +8010153d: 81 fb d4 15 11 80 cmp $0x801115d4,%ebx +80101543: 73 10 jae 80101555 + if (ip->ref > 0 && ip->dev == dev && ip->inum == inum) { +80101545: 8b 43 08 mov 0x8(%ebx),%eax +80101548: 85 c0 test %eax,%eax +8010154a: 0f 8f 50 ff ff ff jg 801014a0 +80101550: e9 68 ff ff ff jmp 801014bd + panic("iget: no inodes"); +80101555: 83 ec 0c sub $0xc,%esp +80101558: 68 c8 74 10 80 push $0x801074c8 +8010155d: e8 2e ee ff ff call 80100390 +80101562: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80101569: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80101570 : +// are listed in ip->addrs[]. The next NINDIRECT blocks are +// listed in block ip->addrs[NDIRECT]. + +// Return the disk block address of the nth block in inode ip. +// If there is no such block, bmap allocates one. +static uint bmap(struct inode *ip, uint bn) { +80101570: 55 push %ebp +80101571: 89 e5 mov %esp,%ebp +80101573: 57 push %edi +80101574: 56 push %esi +80101575: 89 c6 mov %eax,%esi +80101577: 53 push %ebx +80101578: 83 ec 1c sub $0x1c,%esp + uint addr, *a; + struct buf *bp; + + if (bn < NDIRECT) { +8010157b: 83 fa 0b cmp $0xb,%edx +8010157e: 0f 86 8c 00 00 00 jbe 80101610 + if ((addr = ip->addrs[bn]) == 0) { + ip->addrs[bn] = addr = balloc(ip->dev); + } + return addr; + } + bn -= NDIRECT; +80101584: 8d 5a f4 lea -0xc(%edx),%ebx + + if (bn < NINDIRECT) { +80101587: 83 fb 7f cmp $0x7f,%ebx +8010158a: 0f 87 a2 00 00 00 ja 80101632 + // Load indirect block, allocating if necessary. + if ((addr = ip->addrs[NDIRECT]) == 0) { +80101590: 8b 80 8c 00 00 00 mov 0x8c(%eax),%eax +80101596: 85 c0 test %eax,%eax +80101598: 74 5e je 801015f8 + ip->addrs[NDIRECT] = addr = balloc(ip->dev); + } + bp = bread(ip->dev, addr); +8010159a: 83 ec 08 sub $0x8,%esp +8010159d: 50 push %eax +8010159e: ff 36 push (%esi) +801015a0: e8 2b eb ff ff call 801000d0 + a = (uint*)bp->data; + if ((addr = a[bn]) == 0) { +801015a5: 83 c4 10 add $0x10,%esp +801015a8: 8d 5c 98 5c lea 0x5c(%eax,%ebx,4),%ebx + bp = bread(ip->dev, addr); +801015ac: 89 c2 mov %eax,%edx + if ((addr = a[bn]) == 0) { +801015ae: 8b 3b mov (%ebx),%edi +801015b0: 85 ff test %edi,%edi +801015b2: 74 1c je 801015d0 + a[bn] = addr = balloc(ip->dev); + log_write(bp); + } + brelse(bp); +801015b4: 83 ec 0c sub $0xc,%esp +801015b7: 52 push %edx +801015b8: e8 33 ec ff ff call 801001f0 +801015bd: 83 c4 10 add $0x10,%esp + return addr; + } + + panic("bmap: out of range"); +} +801015c0: 8d 65 f4 lea -0xc(%ebp),%esp +801015c3: 89 f8 mov %edi,%eax +801015c5: 5b pop %ebx +801015c6: 5e pop %esi +801015c7: 5f pop %edi +801015c8: 5d pop %ebp +801015c9: c3 ret +801015ca: 8d b6 00 00 00 00 lea 0x0(%esi),%esi +801015d0: 89 45 e4 mov %eax,-0x1c(%ebp) + a[bn] = addr = balloc(ip->dev); +801015d3: 8b 06 mov (%esi),%eax +801015d5: e8 86 fd ff ff call 80101360 + log_write(bp); +801015da: 8b 55 e4 mov -0x1c(%ebp),%edx +801015dd: 83 ec 0c sub $0xc,%esp + a[bn] = addr = balloc(ip->dev); +801015e0: 89 03 mov %eax,(%ebx) +801015e2: 89 c7 mov %eax,%edi + log_write(bp); +801015e4: 52 push %edx +801015e5: e8 76 1a 00 00 call 80103060 +801015ea: 8b 55 e4 mov -0x1c(%ebp),%edx +801015ed: 83 c4 10 add $0x10,%esp +801015f0: eb c2 jmp 801015b4 +801015f2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + ip->addrs[NDIRECT] = addr = balloc(ip->dev); +801015f8: 8b 06 mov (%esi),%eax +801015fa: e8 61 fd ff ff call 80101360 +801015ff: 89 86 8c 00 00 00 mov %eax,0x8c(%esi) +80101605: eb 93 jmp 8010159a +80101607: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010160e: 66 90 xchg %ax,%ax + if ((addr = ip->addrs[bn]) == 0) { +80101610: 8d 5a 14 lea 0x14(%edx),%ebx +80101613: 8b 7c 98 0c mov 0xc(%eax,%ebx,4),%edi +80101617: 85 ff test %edi,%edi +80101619: 75 a5 jne 801015c0 + ip->addrs[bn] = addr = balloc(ip->dev); +8010161b: 8b 00 mov (%eax),%eax +8010161d: e8 3e fd ff ff call 80101360 +80101622: 89 44 9e 0c mov %eax,0xc(%esi,%ebx,4) +80101626: 89 c7 mov %eax,%edi +} +80101628: 8d 65 f4 lea -0xc(%ebp),%esp +8010162b: 5b pop %ebx +8010162c: 89 f8 mov %edi,%eax +8010162e: 5e pop %esi +8010162f: 5f pop %edi +80101630: 5d pop %ebp +80101631: c3 ret + panic("bmap: out of range"); +80101632: 83 ec 0c sub $0xc,%esp +80101635: 68 d8 74 10 80 push $0x801074d8 +8010163a: e8 51 ed ff ff call 80100390 +8010163f: 90 nop + +80101640 : +void readsb(int dev, struct superblock *sb) { +80101640: 55 push %ebp +80101641: 89 e5 mov %esp,%ebp +80101643: 56 push %esi +80101644: 53 push %ebx +80101645: 8b 75 0c mov 0xc(%ebp),%esi + bp = bread(dev, 1); +80101648: 83 ec 08 sub $0x8,%esp +8010164b: 6a 01 push $0x1 +8010164d: ff 75 08 push 0x8(%ebp) +80101650: e8 7b ea ff ff call 801000d0 + memmove(sb, bp->data, sizeof(*sb)); +80101655: 83 c4 0c add $0xc,%esp + bp = bread(dev, 1); +80101658: 89 c3 mov %eax,%ebx + memmove(sb, bp->data, sizeof(*sb)); +8010165a: 8d 40 5c lea 0x5c(%eax),%eax +8010165d: 6a 1c push $0x1c +8010165f: 50 push %eax +80101660: 56 push %esi +80101661: e8 fa 31 00 00 call 80104860 + brelse(bp); +80101666: 89 5d 08 mov %ebx,0x8(%ebp) +80101669: 83 c4 10 add $0x10,%esp +} +8010166c: 8d 65 f8 lea -0x8(%ebp),%esp +8010166f: 5b pop %ebx +80101670: 5e pop %esi +80101671: 5d pop %ebp + brelse(bp); +80101672: e9 79 eb ff ff jmp 801001f0 +80101677: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010167e: 66 90 xchg %ax,%ax + +80101680 : +void iinit(int dev) { +80101680: 55 push %ebp +80101681: 89 e5 mov %esp,%ebp +80101683: 53 push %ebx +80101684: bb c0 f9 10 80 mov $0x8010f9c0,%ebx +80101689: 83 ec 0c sub $0xc,%esp + initlock(&icache.lock, "icache"); +8010168c: 68 eb 74 10 80 push $0x801074eb +80101691: 68 80 f9 10 80 push $0x8010f980 +80101696: e8 95 2e 00 00 call 80104530 + for (i = 0; i < NINODE; i++) { +8010169b: 83 c4 10 add $0x10,%esp +8010169e: 66 90 xchg %ax,%ax + initsleeplock(&icache.inode[i].lock, "inode"); +801016a0: 83 ec 08 sub $0x8,%esp +801016a3: 68 f2 74 10 80 push $0x801074f2 +801016a8: 53 push %ebx + for (i = 0; i < NINODE; i++) { +801016a9: 81 c3 90 00 00 00 add $0x90,%ebx + initsleeplock(&icache.inode[i].lock, "inode"); +801016af: e8 4c 2d 00 00 call 80104400 + for (i = 0; i < NINODE; i++) { +801016b4: 83 c4 10 add $0x10,%esp +801016b7: 81 fb e0 15 11 80 cmp $0x801115e0,%ebx +801016bd: 75 e1 jne 801016a0 + bp = bread(dev, 1); +801016bf: 83 ec 08 sub $0x8,%esp +801016c2: 6a 01 push $0x1 +801016c4: ff 75 08 push 0x8(%ebp) +801016c7: e8 04 ea ff ff call 801000d0 + memmove(sb, bp->data, sizeof(*sb)); +801016cc: 83 c4 0c add $0xc,%esp + bp = bread(dev, 1); +801016cf: 89 c3 mov %eax,%ebx + memmove(sb, bp->data, sizeof(*sb)); +801016d1: 8d 40 5c lea 0x5c(%eax),%eax +801016d4: 6a 1c push $0x1c +801016d6: 50 push %eax +801016d7: 68 d4 15 11 80 push $0x801115d4 +801016dc: e8 7f 31 00 00 call 80104860 + brelse(bp); +801016e1: 89 1c 24 mov %ebx,(%esp) +801016e4: e8 07 eb ff ff call 801001f0 + cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\ +801016e9: ff 35 ec 15 11 80 push 0x801115ec +801016ef: ff 35 e8 15 11 80 push 0x801115e8 +801016f5: ff 35 e4 15 11 80 push 0x801115e4 +801016fb: ff 35 e0 15 11 80 push 0x801115e0 +80101701: ff 35 dc 15 11 80 push 0x801115dc +80101707: ff 35 d8 15 11 80 push 0x801115d8 +8010170d: ff 35 d4 15 11 80 push 0x801115d4 +80101713: 68 58 75 10 80 push $0x80107558 +80101718: e8 93 ef ff ff call 801006b0 +} +8010171d: 8b 5d fc mov -0x4(%ebp),%ebx +80101720: 83 c4 30 add $0x30,%esp +80101723: c9 leave +80101724: c3 ret +80101725: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010172c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80101730 : +struct inode* ialloc(uint dev, short type) { +80101730: 55 push %ebp +80101731: 89 e5 mov %esp,%ebp +80101733: 57 push %edi +80101734: 56 push %esi +80101735: 53 push %ebx +80101736: 83 ec 1c sub $0x1c,%esp +80101739: 8b 45 0c mov 0xc(%ebp),%eax + for (inum = 1; inum < sb.ninodes; inum++) { +8010173c: 83 3d dc 15 11 80 01 cmpl $0x1,0x801115dc +struct inode* ialloc(uint dev, short type) { +80101743: 8b 75 08 mov 0x8(%ebp),%esi +80101746: 89 45 e4 mov %eax,-0x1c(%ebp) + for (inum = 1; inum < sb.ninodes; inum++) { +80101749: 0f 86 91 00 00 00 jbe 801017e0 +8010174f: bf 01 00 00 00 mov $0x1,%edi +80101754: eb 21 jmp 80101777 +80101756: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010175d: 8d 76 00 lea 0x0(%esi),%esi + brelse(bp); +80101760: 83 ec 0c sub $0xc,%esp + for (inum = 1; inum < sb.ninodes; inum++) { +80101763: 83 c7 01 add $0x1,%edi + brelse(bp); +80101766: 53 push %ebx +80101767: e8 84 ea ff ff call 801001f0 + for (inum = 1; inum < sb.ninodes; inum++) { +8010176c: 83 c4 10 add $0x10,%esp +8010176f: 3b 3d dc 15 11 80 cmp 0x801115dc,%edi +80101775: 73 69 jae 801017e0 + bp = bread(dev, IBLOCK(inum, sb)); +80101777: 89 f8 mov %edi,%eax +80101779: 83 ec 08 sub $0x8,%esp +8010177c: c1 e8 03 shr $0x3,%eax +8010177f: 03 05 e8 15 11 80 add 0x801115e8,%eax +80101785: 50 push %eax +80101786: 56 push %esi +80101787: e8 44 e9 ff ff call 801000d0 + if (dip->type == 0) { // a free inode +8010178c: 83 c4 10 add $0x10,%esp + bp = bread(dev, IBLOCK(inum, sb)); +8010178f: 89 c3 mov %eax,%ebx + dip = (struct dinode*)bp->data + inum % IPB; +80101791: 89 f8 mov %edi,%eax +80101793: 83 e0 07 and $0x7,%eax +80101796: c1 e0 06 shl $0x6,%eax +80101799: 8d 4c 03 5c lea 0x5c(%ebx,%eax,1),%ecx + if (dip->type == 0) { // a free inode +8010179d: 66 83 39 00 cmpw $0x0,(%ecx) +801017a1: 75 bd jne 80101760 + memset(dip, 0, sizeof(*dip)); +801017a3: 83 ec 04 sub $0x4,%esp +801017a6: 89 4d e0 mov %ecx,-0x20(%ebp) +801017a9: 6a 40 push $0x40 +801017ab: 6a 00 push $0x0 +801017ad: 51 push %ecx +801017ae: e8 0d 30 00 00 call 801047c0 + dip->type = type; +801017b3: 0f b7 45 e4 movzwl -0x1c(%ebp),%eax +801017b7: 8b 4d e0 mov -0x20(%ebp),%ecx +801017ba: 66 89 01 mov %ax,(%ecx) + log_write(bp); // mark it allocated on the disk +801017bd: 89 1c 24 mov %ebx,(%esp) +801017c0: e8 9b 18 00 00 call 80103060 + brelse(bp); +801017c5: 89 1c 24 mov %ebx,(%esp) +801017c8: e8 23 ea ff ff call 801001f0 + return iget(dev, inum); +801017cd: 83 c4 10 add $0x10,%esp +} +801017d0: 8d 65 f4 lea -0xc(%ebp),%esp + return iget(dev, inum); +801017d3: 89 fa mov %edi,%edx +} +801017d5: 5b pop %ebx + return iget(dev, inum); +801017d6: 89 f0 mov %esi,%eax +} +801017d8: 5e pop %esi +801017d9: 5f pop %edi +801017da: 5d pop %ebp + return iget(dev, inum); +801017db: e9 90 fc ff ff jmp 80101470 + panic("ialloc: no inodes"); +801017e0: 83 ec 0c sub $0xc,%esp +801017e3: 68 f8 74 10 80 push $0x801074f8 +801017e8: e8 a3 eb ff ff call 80100390 +801017ed: 8d 76 00 lea 0x0(%esi),%esi + +801017f0 : +void iupdate(struct inode *ip) { +801017f0: 55 push %ebp +801017f1: 89 e5 mov %esp,%ebp +801017f3: 56 push %esi +801017f4: 53 push %ebx +801017f5: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = bread(ip->dev, IBLOCK(ip->inum, sb)); +801017f8: 8b 43 04 mov 0x4(%ebx),%eax + memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); +801017fb: 83 c3 5c add $0x5c,%ebx + bp = bread(ip->dev, IBLOCK(ip->inum, sb)); +801017fe: 83 ec 08 sub $0x8,%esp +80101801: c1 e8 03 shr $0x3,%eax +80101804: 03 05 e8 15 11 80 add 0x801115e8,%eax +8010180a: 50 push %eax +8010180b: ff 73 a4 push -0x5c(%ebx) +8010180e: e8 bd e8 ff ff call 801000d0 + dip->type = ip->type; +80101813: 0f b7 53 f4 movzwl -0xc(%ebx),%edx + memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); +80101817: 83 c4 0c add $0xc,%esp + bp = bread(ip->dev, IBLOCK(ip->inum, sb)); +8010181a: 89 c6 mov %eax,%esi + dip = (struct dinode*)bp->data + ip->inum % IPB; +8010181c: 8b 43 a8 mov -0x58(%ebx),%eax +8010181f: 83 e0 07 and $0x7,%eax +80101822: c1 e0 06 shl $0x6,%eax +80101825: 8d 44 06 5c lea 0x5c(%esi,%eax,1),%eax + dip->type = ip->type; +80101829: 66 89 10 mov %dx,(%eax) + dip->major = ip->major; +8010182c: 0f b7 53 f6 movzwl -0xa(%ebx),%edx + memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); +80101830: 83 c0 0c add $0xc,%eax + dip->major = ip->major; +80101833: 66 89 50 f6 mov %dx,-0xa(%eax) + dip->minor = ip->minor; +80101837: 0f b7 53 f8 movzwl -0x8(%ebx),%edx +8010183b: 66 89 50 f8 mov %dx,-0x8(%eax) + dip->nlink = ip->nlink; +8010183f: 0f b7 53 fa movzwl -0x6(%ebx),%edx +80101843: 66 89 50 fa mov %dx,-0x6(%eax) + dip->size = ip->size; +80101847: 8b 53 fc mov -0x4(%ebx),%edx +8010184a: 89 50 fc mov %edx,-0x4(%eax) + memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); +8010184d: 6a 34 push $0x34 +8010184f: 53 push %ebx +80101850: 50 push %eax +80101851: e8 0a 30 00 00 call 80104860 + log_write(bp); +80101856: 89 34 24 mov %esi,(%esp) +80101859: e8 02 18 00 00 call 80103060 + brelse(bp); +8010185e: 89 75 08 mov %esi,0x8(%ebp) +80101861: 83 c4 10 add $0x10,%esp +} +80101864: 8d 65 f8 lea -0x8(%ebp),%esp +80101867: 5b pop %ebx +80101868: 5e pop %esi +80101869: 5d pop %ebp + brelse(bp); +8010186a: e9 81 e9 ff ff jmp 801001f0 +8010186f: 90 nop + +80101870 : +struct inode* idup(struct inode *ip) { +80101870: 55 push %ebp +80101871: 89 e5 mov %esp,%ebp +80101873: 53 push %ebx +80101874: 83 ec 10 sub $0x10,%esp +80101877: 8b 5d 08 mov 0x8(%ebp),%ebx + acquire(&icache.lock); +8010187a: 68 80 f9 10 80 push $0x8010f980 +8010187f: e8 7c 2e 00 00 call 80104700 + ip->ref++; +80101884: 83 43 08 01 addl $0x1,0x8(%ebx) + release(&icache.lock); +80101888: c7 04 24 80 f9 10 80 movl $0x8010f980,(%esp) +8010188f: e8 0c 2e 00 00 call 801046a0 +} +80101894: 89 d8 mov %ebx,%eax +80101896: 8b 5d fc mov -0x4(%ebp),%ebx +80101899: c9 leave +8010189a: c3 ret +8010189b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010189f: 90 nop + +801018a0 : +void ilock(struct inode *ip) { +801018a0: 55 push %ebp +801018a1: 89 e5 mov %esp,%ebp +801018a3: 56 push %esi +801018a4: 53 push %ebx +801018a5: 8b 5d 08 mov 0x8(%ebp),%ebx + if (ip == 0 || ip->ref < 1) { +801018a8: 85 db test %ebx,%ebx +801018aa: 0f 84 b7 00 00 00 je 80101967 +801018b0: 8b 53 08 mov 0x8(%ebx),%edx +801018b3: 85 d2 test %edx,%edx +801018b5: 0f 8e ac 00 00 00 jle 80101967 + acquiresleep(&ip->lock); +801018bb: 83 ec 0c sub $0xc,%esp +801018be: 8d 43 0c lea 0xc(%ebx),%eax +801018c1: 50 push %eax +801018c2: e8 79 2b 00 00 call 80104440 + if (ip->valid == 0) { +801018c7: 8b 43 4c mov 0x4c(%ebx),%eax +801018ca: 83 c4 10 add $0x10,%esp +801018cd: 85 c0 test %eax,%eax +801018cf: 74 0f je 801018e0 +} +801018d1: 8d 65 f8 lea -0x8(%ebp),%esp +801018d4: 5b pop %ebx +801018d5: 5e pop %esi +801018d6: 5d pop %ebp +801018d7: c3 ret +801018d8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801018df: 90 nop + bp = bread(ip->dev, IBLOCK(ip->inum, sb)); +801018e0: 8b 43 04 mov 0x4(%ebx),%eax +801018e3: 83 ec 08 sub $0x8,%esp +801018e6: c1 e8 03 shr $0x3,%eax +801018e9: 03 05 e8 15 11 80 add 0x801115e8,%eax +801018ef: 50 push %eax +801018f0: ff 33 push (%ebx) +801018f2: e8 d9 e7 ff ff call 801000d0 + memmove(ip->addrs, dip->addrs, sizeof(ip->addrs)); +801018f7: 83 c4 0c add $0xc,%esp + bp = bread(ip->dev, IBLOCK(ip->inum, sb)); +801018fa: 89 c6 mov %eax,%esi + dip = (struct dinode*)bp->data + ip->inum % IPB; +801018fc: 8b 43 04 mov 0x4(%ebx),%eax +801018ff: 83 e0 07 and $0x7,%eax +80101902: c1 e0 06 shl $0x6,%eax +80101905: 8d 44 06 5c lea 0x5c(%esi,%eax,1),%eax + ip->type = dip->type; +80101909: 0f b7 10 movzwl (%eax),%edx + memmove(ip->addrs, dip->addrs, sizeof(ip->addrs)); +8010190c: 83 c0 0c add $0xc,%eax + ip->type = dip->type; +8010190f: 66 89 53 50 mov %dx,0x50(%ebx) + ip->major = dip->major; +80101913: 0f b7 50 f6 movzwl -0xa(%eax),%edx +80101917: 66 89 53 52 mov %dx,0x52(%ebx) + ip->minor = dip->minor; +8010191b: 0f b7 50 f8 movzwl -0x8(%eax),%edx +8010191f: 66 89 53 54 mov %dx,0x54(%ebx) + ip->nlink = dip->nlink; +80101923: 0f b7 50 fa movzwl -0x6(%eax),%edx +80101927: 66 89 53 56 mov %dx,0x56(%ebx) + ip->size = dip->size; +8010192b: 8b 50 fc mov -0x4(%eax),%edx +8010192e: 89 53 58 mov %edx,0x58(%ebx) + memmove(ip->addrs, dip->addrs, sizeof(ip->addrs)); +80101931: 6a 34 push $0x34 +80101933: 50 push %eax +80101934: 8d 43 5c lea 0x5c(%ebx),%eax +80101937: 50 push %eax +80101938: e8 23 2f 00 00 call 80104860 + brelse(bp); +8010193d: 89 34 24 mov %esi,(%esp) +80101940: e8 ab e8 ff ff call 801001f0 + if (ip->type == 0) { +80101945: 83 c4 10 add $0x10,%esp +80101948: 66 83 7b 50 00 cmpw $0x0,0x50(%ebx) + ip->valid = 1; +8010194d: c7 43 4c 01 00 00 00 movl $0x1,0x4c(%ebx) + if (ip->type == 0) { +80101954: 0f 85 77 ff ff ff jne 801018d1 + panic("ilock: no type"); +8010195a: 83 ec 0c sub $0xc,%esp +8010195d: 68 10 75 10 80 push $0x80107510 +80101962: e8 29 ea ff ff call 80100390 + panic("ilock"); +80101967: 83 ec 0c sub $0xc,%esp +8010196a: 68 0a 75 10 80 push $0x8010750a +8010196f: e8 1c ea ff ff call 80100390 +80101974: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010197b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010197f: 90 nop + +80101980 : +void iunlock(struct inode *ip) { +80101980: 55 push %ebp +80101981: 89 e5 mov %esp,%ebp +80101983: 56 push %esi +80101984: 53 push %ebx +80101985: 8b 5d 08 mov 0x8(%ebp),%ebx + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { +80101988: 85 db test %ebx,%ebx +8010198a: 74 28 je 801019b4 +8010198c: 83 ec 0c sub $0xc,%esp +8010198f: 8d 73 0c lea 0xc(%ebx),%esi +80101992: 56 push %esi +80101993: e8 48 2b 00 00 call 801044e0 +80101998: 83 c4 10 add $0x10,%esp +8010199b: 85 c0 test %eax,%eax +8010199d: 74 15 je 801019b4 +8010199f: 8b 43 08 mov 0x8(%ebx),%eax +801019a2: 85 c0 test %eax,%eax +801019a4: 7e 0e jle 801019b4 + releasesleep(&ip->lock); +801019a6: 89 75 08 mov %esi,0x8(%ebp) +} +801019a9: 8d 65 f8 lea -0x8(%ebp),%esp +801019ac: 5b pop %ebx +801019ad: 5e pop %esi +801019ae: 5d pop %ebp + releasesleep(&ip->lock); +801019af: e9 ec 2a 00 00 jmp 801044a0 + panic("iunlock"); +801019b4: 83 ec 0c sub $0xc,%esp +801019b7: 68 1f 75 10 80 push $0x8010751f +801019bc: e8 cf e9 ff ff call 80100390 +801019c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801019c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801019cf: 90 nop + +801019d0 : +void iput(struct inode *ip) { +801019d0: 55 push %ebp +801019d1: 89 e5 mov %esp,%ebp +801019d3: 57 push %edi +801019d4: 56 push %esi +801019d5: 53 push %ebx +801019d6: 83 ec 28 sub $0x28,%esp +801019d9: 8b 5d 08 mov 0x8(%ebp),%ebx + acquiresleep(&ip->lock); +801019dc: 8d 7b 0c lea 0xc(%ebx),%edi +801019df: 57 push %edi +801019e0: e8 5b 2a 00 00 call 80104440 + if (ip->valid && ip->nlink == 0) { +801019e5: 8b 53 4c mov 0x4c(%ebx),%edx +801019e8: 83 c4 10 add $0x10,%esp +801019eb: 85 d2 test %edx,%edx +801019ed: 74 07 je 801019f6 +801019ef: 66 83 7b 56 00 cmpw $0x0,0x56(%ebx) +801019f4: 74 32 je 80101a28 + releasesleep(&ip->lock); +801019f6: 83 ec 0c sub $0xc,%esp +801019f9: 57 push %edi +801019fa: e8 a1 2a 00 00 call 801044a0 + acquire(&icache.lock); +801019ff: c7 04 24 80 f9 10 80 movl $0x8010f980,(%esp) +80101a06: e8 f5 2c 00 00 call 80104700 + ip->ref--; +80101a0b: 83 6b 08 01 subl $0x1,0x8(%ebx) + release(&icache.lock); +80101a0f: 83 c4 10 add $0x10,%esp +80101a12: c7 45 08 80 f9 10 80 movl $0x8010f980,0x8(%ebp) +} +80101a19: 8d 65 f4 lea -0xc(%ebp),%esp +80101a1c: 5b pop %ebx +80101a1d: 5e pop %esi +80101a1e: 5f pop %edi +80101a1f: 5d pop %ebp + release(&icache.lock); +80101a20: e9 7b 2c 00 00 jmp 801046a0 +80101a25: 8d 76 00 lea 0x0(%esi),%esi + acquire(&icache.lock); +80101a28: 83 ec 0c sub $0xc,%esp +80101a2b: 68 80 f9 10 80 push $0x8010f980 +80101a30: e8 cb 2c 00 00 call 80104700 + int r = ip->ref; +80101a35: 8b 73 08 mov 0x8(%ebx),%esi + release(&icache.lock); +80101a38: c7 04 24 80 f9 10 80 movl $0x8010f980,(%esp) +80101a3f: e8 5c 2c 00 00 call 801046a0 + if (r == 1) { +80101a44: 83 c4 10 add $0x10,%esp +80101a47: 83 fe 01 cmp $0x1,%esi +80101a4a: 75 aa jne 801019f6 +80101a4c: 8d 8b 8c 00 00 00 lea 0x8c(%ebx),%ecx +80101a52: 89 7d e4 mov %edi,-0x1c(%ebp) +80101a55: 8d 73 5c lea 0x5c(%ebx),%esi +80101a58: 89 cf mov %ecx,%edi +80101a5a: eb 0b jmp 80101a67 +80101a5c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +static void itrunc(struct inode *ip) { + int i, j; + struct buf *bp; + uint *a; + + for (i = 0; i < NDIRECT; i++) { +80101a60: 83 c6 04 add $0x4,%esi +80101a63: 39 fe cmp %edi,%esi +80101a65: 74 19 je 80101a80 + if (ip->addrs[i]) { +80101a67: 8b 16 mov (%esi),%edx +80101a69: 85 d2 test %edx,%edx +80101a6b: 74 f3 je 80101a60 + bfree(ip->dev, ip->addrs[i]); +80101a6d: 8b 03 mov (%ebx),%eax +80101a6f: e8 6c f8 ff ff call 801012e0 + ip->addrs[i] = 0; +80101a74: c7 06 00 00 00 00 movl $0x0,(%esi) +80101a7a: eb e4 jmp 80101a60 +80101a7c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + } + } + + if (ip->addrs[NDIRECT]) { +80101a80: 8b 83 8c 00 00 00 mov 0x8c(%ebx),%eax +80101a86: 8b 7d e4 mov -0x1c(%ebp),%edi +80101a89: 85 c0 test %eax,%eax +80101a8b: 75 2d jne 80101aba + bfree(ip->dev, ip->addrs[NDIRECT]); + ip->addrs[NDIRECT] = 0; + } + + ip->size = 0; + iupdate(ip); +80101a8d: 83 ec 0c sub $0xc,%esp + ip->size = 0; +80101a90: c7 43 58 00 00 00 00 movl $0x0,0x58(%ebx) + iupdate(ip); +80101a97: 53 push %ebx +80101a98: e8 53 fd ff ff call 801017f0 + ip->type = 0; +80101a9d: 31 c0 xor %eax,%eax +80101a9f: 66 89 43 50 mov %ax,0x50(%ebx) + iupdate(ip); +80101aa3: 89 1c 24 mov %ebx,(%esp) +80101aa6: e8 45 fd ff ff call 801017f0 + ip->valid = 0; +80101aab: c7 43 4c 00 00 00 00 movl $0x0,0x4c(%ebx) +80101ab2: 83 c4 10 add $0x10,%esp +80101ab5: e9 3c ff ff ff jmp 801019f6 + bp = bread(ip->dev, ip->addrs[NDIRECT]); +80101aba: 83 ec 08 sub $0x8,%esp +80101abd: 50 push %eax +80101abe: ff 33 push (%ebx) +80101ac0: e8 0b e6 ff ff call 801000d0 +80101ac5: 89 7d e0 mov %edi,-0x20(%ebp) +80101ac8: 83 c4 10 add $0x10,%esp +80101acb: 8d 88 5c 02 00 00 lea 0x25c(%eax),%ecx +80101ad1: 89 45 e4 mov %eax,-0x1c(%ebp) + for (j = 0; j < NINDIRECT; j++) { +80101ad4: 8d 70 5c lea 0x5c(%eax),%esi +80101ad7: 89 cf mov %ecx,%edi +80101ad9: eb 0c jmp 80101ae7 +80101adb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80101adf: 90 nop +80101ae0: 83 c6 04 add $0x4,%esi +80101ae3: 39 f7 cmp %esi,%edi +80101ae5: 74 0f je 80101af6 + if (a[j]) { +80101ae7: 8b 16 mov (%esi),%edx +80101ae9: 85 d2 test %edx,%edx +80101aeb: 74 f3 je 80101ae0 + bfree(ip->dev, a[j]); +80101aed: 8b 03 mov (%ebx),%eax +80101aef: e8 ec f7 ff ff call 801012e0 +80101af4: eb ea jmp 80101ae0 + brelse(bp); +80101af6: 83 ec 0c sub $0xc,%esp +80101af9: ff 75 e4 push -0x1c(%ebp) +80101afc: 8b 7d e0 mov -0x20(%ebp),%edi +80101aff: e8 ec e6 ff ff call 801001f0 + bfree(ip->dev, ip->addrs[NDIRECT]); +80101b04: 8b 93 8c 00 00 00 mov 0x8c(%ebx),%edx +80101b0a: 8b 03 mov (%ebx),%eax +80101b0c: e8 cf f7 ff ff call 801012e0 + ip->addrs[NDIRECT] = 0; +80101b11: 83 c4 10 add $0x10,%esp +80101b14: c7 83 8c 00 00 00 00 movl $0x0,0x8c(%ebx) +80101b1b: 00 00 00 +80101b1e: e9 6a ff ff ff jmp 80101a8d +80101b23: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80101b2a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80101b30 : +void iunlockput(struct inode *ip) { +80101b30: 55 push %ebp +80101b31: 89 e5 mov %esp,%ebp +80101b33: 56 push %esi +80101b34: 53 push %ebx +80101b35: 8b 5d 08 mov 0x8(%ebp),%ebx + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { +80101b38: 85 db test %ebx,%ebx +80101b3a: 74 34 je 80101b70 +80101b3c: 83 ec 0c sub $0xc,%esp +80101b3f: 8d 73 0c lea 0xc(%ebx),%esi +80101b42: 56 push %esi +80101b43: e8 98 29 00 00 call 801044e0 +80101b48: 83 c4 10 add $0x10,%esp +80101b4b: 85 c0 test %eax,%eax +80101b4d: 74 21 je 80101b70 +80101b4f: 8b 43 08 mov 0x8(%ebx),%eax +80101b52: 85 c0 test %eax,%eax +80101b54: 7e 1a jle 80101b70 + releasesleep(&ip->lock); +80101b56: 83 ec 0c sub $0xc,%esp +80101b59: 56 push %esi +80101b5a: e8 41 29 00 00 call 801044a0 + iput(ip); +80101b5f: 89 5d 08 mov %ebx,0x8(%ebp) +80101b62: 83 c4 10 add $0x10,%esp +} +80101b65: 8d 65 f8 lea -0x8(%ebp),%esp +80101b68: 5b pop %ebx +80101b69: 5e pop %esi +80101b6a: 5d pop %ebp + iput(ip); +80101b6b: e9 60 fe ff ff jmp 801019d0 + panic("iunlock"); +80101b70: 83 ec 0c sub $0xc,%esp +80101b73: 68 1f 75 10 80 push $0x8010751f +80101b78: e8 13 e8 ff ff call 80100390 +80101b7d: 8d 76 00 lea 0x0(%esi),%esi + +80101b80 : +} + +// Copy stat information from inode. +// Caller must hold ip->lock. +void stati(struct inode *ip, struct stat *st) { +80101b80: 55 push %ebp +80101b81: 89 e5 mov %esp,%ebp +80101b83: 8b 55 08 mov 0x8(%ebp),%edx +80101b86: 8b 45 0c mov 0xc(%ebp),%eax + st->dev = ip->dev; +80101b89: 8b 0a mov (%edx),%ecx +80101b8b: 89 48 04 mov %ecx,0x4(%eax) + st->ino = ip->inum; +80101b8e: 8b 4a 04 mov 0x4(%edx),%ecx +80101b91: 89 48 08 mov %ecx,0x8(%eax) + st->type = ip->type; +80101b94: 0f b7 4a 50 movzwl 0x50(%edx),%ecx +80101b98: 66 89 08 mov %cx,(%eax) + st->nlink = ip->nlink; +80101b9b: 0f b7 4a 56 movzwl 0x56(%edx),%ecx +80101b9f: 66 89 48 0c mov %cx,0xc(%eax) + st->size = ip->size; +80101ba3: 8b 52 58 mov 0x58(%edx),%edx +80101ba6: 89 50 10 mov %edx,0x10(%eax) +} +80101ba9: 5d pop %ebp +80101baa: c3 ret +80101bab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80101baf: 90 nop + +80101bb0 : + + +// Read data from inode. +// Caller must hold ip->lock. +int readi(struct inode *ip, char *dst, uint off, uint n) { +80101bb0: 55 push %ebp +80101bb1: 89 e5 mov %esp,%ebp +80101bb3: 57 push %edi +80101bb4: 56 push %esi +80101bb5: 53 push %ebx +80101bb6: 83 ec 1c sub $0x1c,%esp +80101bb9: 8b 7d 0c mov 0xc(%ebp),%edi +80101bbc: 8b 45 08 mov 0x8(%ebp),%eax +80101bbf: 8b 75 10 mov 0x10(%ebp),%esi +80101bc2: 89 7d e0 mov %edi,-0x20(%ebp) +80101bc5: 8b 7d 14 mov 0x14(%ebp),%edi + uint tot, m; + struct buf *bp; + + if (ip->type == T_DEV) { +80101bc8: 66 83 78 50 03 cmpw $0x3,0x50(%eax) +int readi(struct inode *ip, char *dst, uint off, uint n) { +80101bcd: 89 45 d8 mov %eax,-0x28(%ebp) +80101bd0: 89 7d e4 mov %edi,-0x1c(%ebp) + if (ip->type == T_DEV) { +80101bd3: 0f 84 a7 00 00 00 je 80101c80 + return -1; + } + return devsw[ip->major].read(ip, dst, n); + } + + if (off > ip->size || off + n < off) { +80101bd9: 8b 45 d8 mov -0x28(%ebp),%eax +80101bdc: 8b 40 58 mov 0x58(%eax),%eax +80101bdf: 39 c6 cmp %eax,%esi +80101be1: 0f 87 ba 00 00 00 ja 80101ca1 +80101be7: 8b 5d e4 mov -0x1c(%ebp),%ebx +80101bea: 31 c9 xor %ecx,%ecx +80101bec: 89 da mov %ebx,%edx +80101bee: 01 f2 add %esi,%edx +80101bf0: 0f 92 c1 setb %cl +80101bf3: 89 cf mov %ecx,%edi +80101bf5: 0f 82 a6 00 00 00 jb 80101ca1 + return -1; + } + if (off + n > ip->size) { + n = ip->size - off; +80101bfb: 89 c1 mov %eax,%ecx +80101bfd: 29 f1 sub %esi,%ecx +80101bff: 39 d0 cmp %edx,%eax +80101c01: 0f 43 cb cmovae %ebx,%ecx +80101c04: 89 4d e4 mov %ecx,-0x1c(%ebp) + } + + for (tot = 0; tot < n; tot += m, off += m, dst += m) { +80101c07: 85 c9 test %ecx,%ecx +80101c09: 74 67 je 80101c72 +80101c0b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80101c0f: 90 nop + bp = bread(ip->dev, bmap(ip, off / BSIZE)); +80101c10: 8b 5d d8 mov -0x28(%ebp),%ebx +80101c13: 89 f2 mov %esi,%edx +80101c15: c1 ea 09 shr $0x9,%edx +80101c18: 89 d8 mov %ebx,%eax +80101c1a: e8 51 f9 ff ff call 80101570 +80101c1f: 83 ec 08 sub $0x8,%esp +80101c22: 50 push %eax +80101c23: ff 33 push (%ebx) +80101c25: e8 a6 e4 ff ff call 801000d0 + m = min(n - tot, BSIZE - off % BSIZE); +80101c2a: 8b 5d e4 mov -0x1c(%ebp),%ebx +80101c2d: b9 00 02 00 00 mov $0x200,%ecx + bp = bread(ip->dev, bmap(ip, off / BSIZE)); +80101c32: 89 c2 mov %eax,%edx + m = min(n - tot, BSIZE - off % BSIZE); +80101c34: 89 f0 mov %esi,%eax +80101c36: 25 ff 01 00 00 and $0x1ff,%eax +80101c3b: 29 fb sub %edi,%ebx + memmove(dst, bp->data + off % BSIZE, m); +80101c3d: 89 55 dc mov %edx,-0x24(%ebp) + m = min(n - tot, BSIZE - off % BSIZE); +80101c40: 29 c1 sub %eax,%ecx + memmove(dst, bp->data + off % BSIZE, m); +80101c42: 8d 44 02 5c lea 0x5c(%edx,%eax,1),%eax + m = min(n - tot, BSIZE - off % BSIZE); +80101c46: 39 d9 cmp %ebx,%ecx +80101c48: 0f 46 d9 cmovbe %ecx,%ebx + memmove(dst, bp->data + off % BSIZE, m); +80101c4b: 83 c4 0c add $0xc,%esp +80101c4e: 53 push %ebx + for (tot = 0; tot < n; tot += m, off += m, dst += m) { +80101c4f: 01 df add %ebx,%edi +80101c51: 01 de add %ebx,%esi + memmove(dst, bp->data + off % BSIZE, m); +80101c53: 50 push %eax +80101c54: ff 75 e0 push -0x20(%ebp) +80101c57: e8 04 2c 00 00 call 80104860 + brelse(bp); +80101c5c: 8b 55 dc mov -0x24(%ebp),%edx +80101c5f: 89 14 24 mov %edx,(%esp) +80101c62: e8 89 e5 ff ff call 801001f0 + for (tot = 0; tot < n; tot += m, off += m, dst += m) { +80101c67: 01 5d e0 add %ebx,-0x20(%ebp) +80101c6a: 83 c4 10 add $0x10,%esp +80101c6d: 39 7d e4 cmp %edi,-0x1c(%ebp) +80101c70: 77 9e ja 80101c10 + } + return n; +80101c72: 8b 45 e4 mov -0x1c(%ebp),%eax +} +80101c75: 8d 65 f4 lea -0xc(%ebp),%esp +80101c78: 5b pop %ebx +80101c79: 5e pop %esi +80101c7a: 5f pop %edi +80101c7b: 5d pop %ebp +80101c7c: c3 ret +80101c7d: 8d 76 00 lea 0x0(%esi),%esi + if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read) { +80101c80: 0f bf 40 52 movswl 0x52(%eax),%eax +80101c84: 66 83 f8 09 cmp $0x9,%ax +80101c88: 77 17 ja 80101ca1 +80101c8a: 8b 04 c5 20 f9 10 80 mov -0x7fef06e0(,%eax,8),%eax +80101c91: 85 c0 test %eax,%eax +80101c93: 74 0c je 80101ca1 + return devsw[ip->major].read(ip, dst, n); +80101c95: 89 7d 10 mov %edi,0x10(%ebp) +} +80101c98: 8d 65 f4 lea -0xc(%ebp),%esp +80101c9b: 5b pop %ebx +80101c9c: 5e pop %esi +80101c9d: 5f pop %edi +80101c9e: 5d pop %ebp + return devsw[ip->major].read(ip, dst, n); +80101c9f: ff e0 jmp *%eax + return -1; +80101ca1: b8 ff ff ff ff mov $0xffffffff,%eax +80101ca6: eb cd jmp 80101c75 +80101ca8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80101caf: 90 nop + +80101cb0 : + +// Write data to inode. +// Caller must hold ip->lock. +int writei(struct inode *ip, char *src, uint off, uint n) { +80101cb0: 55 push %ebp +80101cb1: 89 e5 mov %esp,%ebp +80101cb3: 57 push %edi +80101cb4: 56 push %esi +80101cb5: 53 push %ebx +80101cb6: 83 ec 1c sub $0x1c,%esp +80101cb9: 8b 45 08 mov 0x8(%ebp),%eax +80101cbc: 8b 75 0c mov 0xc(%ebp),%esi +80101cbf: 8b 55 14 mov 0x14(%ebp),%edx + uint tot, m; + struct buf *bp; + + if (ip->type == T_DEV) { +80101cc2: 66 83 78 50 03 cmpw $0x3,0x50(%eax) +int writei(struct inode *ip, char *src, uint off, uint n) { +80101cc7: 89 75 dc mov %esi,-0x24(%ebp) +80101cca: 89 45 d8 mov %eax,-0x28(%ebp) +80101ccd: 8b 75 10 mov 0x10(%ebp),%esi +80101cd0: 89 55 e0 mov %edx,-0x20(%ebp) + if (ip->type == T_DEV) { +80101cd3: 0f 84 b7 00 00 00 je 80101d90 + return -1; + } + return devsw[ip->major].write(ip, src, n); + } + + if (off > ip->size || off + n < off) { +80101cd9: 8b 45 d8 mov -0x28(%ebp),%eax +80101cdc: 3b 70 58 cmp 0x58(%eax),%esi +80101cdf: 0f 87 e7 00 00 00 ja 80101dcc +80101ce5: 8b 7d e0 mov -0x20(%ebp),%edi +80101ce8: 31 d2 xor %edx,%edx +80101cea: 89 f8 mov %edi,%eax +80101cec: 01 f0 add %esi,%eax +80101cee: 0f 92 c2 setb %dl + return -1; + } + if (off + n > MAXFILE * BSIZE) { +80101cf1: 3d 00 18 01 00 cmp $0x11800,%eax +80101cf6: 0f 87 d0 00 00 00 ja 80101dcc +80101cfc: 85 d2 test %edx,%edx +80101cfe: 0f 85 c8 00 00 00 jne 80101dcc + return -1; + } + + for (tot = 0; tot < n; tot += m, off += m, src += m) { +80101d04: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +80101d0b: 85 ff test %edi,%edi +80101d0d: 74 72 je 80101d81 +80101d0f: 90 nop + bp = bread(ip->dev, bmap(ip, off / BSIZE)); +80101d10: 8b 7d d8 mov -0x28(%ebp),%edi +80101d13: 89 f2 mov %esi,%edx +80101d15: c1 ea 09 shr $0x9,%edx +80101d18: 89 f8 mov %edi,%eax +80101d1a: e8 51 f8 ff ff call 80101570 +80101d1f: 83 ec 08 sub $0x8,%esp +80101d22: 50 push %eax +80101d23: ff 37 push (%edi) +80101d25: e8 a6 e3 ff ff call 801000d0 + m = min(n - tot, BSIZE - off % BSIZE); +80101d2a: b9 00 02 00 00 mov $0x200,%ecx +80101d2f: 8b 5d e0 mov -0x20(%ebp),%ebx +80101d32: 2b 5d e4 sub -0x1c(%ebp),%ebx + bp = bread(ip->dev, bmap(ip, off / BSIZE)); +80101d35: 89 c7 mov %eax,%edi + m = min(n - tot, BSIZE - off % BSIZE); +80101d37: 89 f0 mov %esi,%eax +80101d39: 25 ff 01 00 00 and $0x1ff,%eax +80101d3e: 29 c1 sub %eax,%ecx + memmove(bp->data + off % BSIZE, src, m); +80101d40: 8d 44 07 5c lea 0x5c(%edi,%eax,1),%eax + m = min(n - tot, BSIZE - off % BSIZE); +80101d44: 39 d9 cmp %ebx,%ecx +80101d46: 0f 46 d9 cmovbe %ecx,%ebx + memmove(bp->data + off % BSIZE, src, m); +80101d49: 83 c4 0c add $0xc,%esp +80101d4c: 53 push %ebx + for (tot = 0; tot < n; tot += m, off += m, src += m) { +80101d4d: 01 de add %ebx,%esi + memmove(bp->data + off % BSIZE, src, m); +80101d4f: ff 75 dc push -0x24(%ebp) +80101d52: 50 push %eax +80101d53: e8 08 2b 00 00 call 80104860 + log_write(bp); +80101d58: 89 3c 24 mov %edi,(%esp) +80101d5b: e8 00 13 00 00 call 80103060 + brelse(bp); +80101d60: 89 3c 24 mov %edi,(%esp) +80101d63: e8 88 e4 ff ff call 801001f0 + for (tot = 0; tot < n; tot += m, off += m, src += m) { +80101d68: 01 5d e4 add %ebx,-0x1c(%ebp) +80101d6b: 83 c4 10 add $0x10,%esp +80101d6e: 8b 45 e4 mov -0x1c(%ebp),%eax +80101d71: 01 5d dc add %ebx,-0x24(%ebp) +80101d74: 39 45 e0 cmp %eax,-0x20(%ebp) +80101d77: 77 97 ja 80101d10 + } + + if (n > 0 && off > ip->size) { +80101d79: 8b 45 d8 mov -0x28(%ebp),%eax +80101d7c: 3b 70 58 cmp 0x58(%eax),%esi +80101d7f: 77 37 ja 80101db8 + ip->size = off; + iupdate(ip); + } + return n; +80101d81: 8b 45 e0 mov -0x20(%ebp),%eax +} +80101d84: 8d 65 f4 lea -0xc(%ebp),%esp +80101d87: 5b pop %ebx +80101d88: 5e pop %esi +80101d89: 5f pop %edi +80101d8a: 5d pop %ebp +80101d8b: c3 ret +80101d8c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write) { +80101d90: 0f bf 40 52 movswl 0x52(%eax),%eax +80101d94: 66 83 f8 09 cmp $0x9,%ax +80101d98: 77 32 ja 80101dcc +80101d9a: 8b 04 c5 24 f9 10 80 mov -0x7fef06dc(,%eax,8),%eax +80101da1: 85 c0 test %eax,%eax +80101da3: 74 27 je 80101dcc + return devsw[ip->major].write(ip, src, n); +80101da5: 89 55 10 mov %edx,0x10(%ebp) +} +80101da8: 8d 65 f4 lea -0xc(%ebp),%esp +80101dab: 5b pop %ebx +80101dac: 5e pop %esi +80101dad: 5f pop %edi +80101dae: 5d pop %ebp + return devsw[ip->major].write(ip, src, n); +80101daf: ff e0 jmp *%eax +80101db1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + ip->size = off; +80101db8: 8b 45 d8 mov -0x28(%ebp),%eax + iupdate(ip); +80101dbb: 83 ec 0c sub $0xc,%esp + ip->size = off; +80101dbe: 89 70 58 mov %esi,0x58(%eax) + iupdate(ip); +80101dc1: 50 push %eax +80101dc2: e8 29 fa ff ff call 801017f0 +80101dc7: 83 c4 10 add $0x10,%esp +80101dca: eb b5 jmp 80101d81 + return -1; +80101dcc: b8 ff ff ff ff mov $0xffffffff,%eax +80101dd1: eb b1 jmp 80101d84 +80101dd3: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80101dda: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80101de0 : + + +// Directories + +int namecmp(const char *s, const char *t) { +80101de0: 55 push %ebp +80101de1: 89 e5 mov %esp,%ebp +80101de3: 83 ec 0c sub $0xc,%esp + return strncmp(s, t, DIRSIZ); +80101de6: 6a 0e push $0xe +80101de8: ff 75 0c push 0xc(%ebp) +80101deb: ff 75 08 push 0x8(%ebp) +80101dee: e8 dd 2a 00 00 call 801048d0 +} +80101df3: c9 leave +80101df4: c3 ret +80101df5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80101dfc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80101e00 : + +// Look for a directory entry in a directory. +// If found, set *poff to byte offset of entry. +struct inode* dirlookup(struct inode *dp, char *name, uint *poff) { +80101e00: 55 push %ebp +80101e01: 89 e5 mov %esp,%ebp +80101e03: 57 push %edi +80101e04: 56 push %esi +80101e05: 53 push %ebx +80101e06: 83 ec 1c sub $0x1c,%esp +80101e09: 8b 5d 08 mov 0x8(%ebp),%ebx + uint off, inum; + struct dirent de; + + if (dp->type != T_DIR) { +80101e0c: 66 83 7b 50 01 cmpw $0x1,0x50(%ebx) +80101e11: 0f 85 85 00 00 00 jne 80101e9c + panic("dirlookup not DIR"); + } + + for (off = 0; off < dp->size; off += sizeof(de)) { +80101e17: 8b 53 58 mov 0x58(%ebx),%edx +80101e1a: 31 ff xor %edi,%edi +80101e1c: 8d 75 d8 lea -0x28(%ebp),%esi +80101e1f: 85 d2 test %edx,%edx +80101e21: 74 3e je 80101e61 +80101e23: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80101e27: 90 nop + if (readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { +80101e28: 6a 10 push $0x10 +80101e2a: 57 push %edi +80101e2b: 56 push %esi +80101e2c: 53 push %ebx +80101e2d: e8 7e fd ff ff call 80101bb0 +80101e32: 83 c4 10 add $0x10,%esp +80101e35: 83 f8 10 cmp $0x10,%eax +80101e38: 75 55 jne 80101e8f + panic("dirlookup read"); + } + if (de.inum == 0) { +80101e3a: 66 83 7d d8 00 cmpw $0x0,-0x28(%ebp) +80101e3f: 74 18 je 80101e59 + return strncmp(s, t, DIRSIZ); +80101e41: 83 ec 04 sub $0x4,%esp +80101e44: 8d 45 da lea -0x26(%ebp),%eax +80101e47: 6a 0e push $0xe +80101e49: 50 push %eax +80101e4a: ff 75 0c push 0xc(%ebp) +80101e4d: e8 7e 2a 00 00 call 801048d0 + continue; + } + if (namecmp(name, de.name) == 0) { +80101e52: 83 c4 10 add $0x10,%esp +80101e55: 85 c0 test %eax,%eax +80101e57: 74 17 je 80101e70 + for (off = 0; off < dp->size; off += sizeof(de)) { +80101e59: 83 c7 10 add $0x10,%edi +80101e5c: 3b 7b 58 cmp 0x58(%ebx),%edi +80101e5f: 72 c7 jb 80101e28 + return iget(dp->dev, inum); + } + } + + return 0; +} +80101e61: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; +80101e64: 31 c0 xor %eax,%eax +} +80101e66: 5b pop %ebx +80101e67: 5e pop %esi +80101e68: 5f pop %edi +80101e69: 5d pop %ebp +80101e6a: c3 ret +80101e6b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80101e6f: 90 nop + if (poff) { +80101e70: 8b 45 10 mov 0x10(%ebp),%eax +80101e73: 85 c0 test %eax,%eax +80101e75: 74 05 je 80101e7c + *poff = off; +80101e77: 8b 45 10 mov 0x10(%ebp),%eax +80101e7a: 89 38 mov %edi,(%eax) + inum = de.inum; +80101e7c: 0f b7 55 d8 movzwl -0x28(%ebp),%edx + return iget(dp->dev, inum); +80101e80: 8b 03 mov (%ebx),%eax +80101e82: e8 e9 f5 ff ff call 80101470 +} +80101e87: 8d 65 f4 lea -0xc(%ebp),%esp +80101e8a: 5b pop %ebx +80101e8b: 5e pop %esi +80101e8c: 5f pop %edi +80101e8d: 5d pop %ebp +80101e8e: c3 ret + panic("dirlookup read"); +80101e8f: 83 ec 0c sub $0xc,%esp +80101e92: 68 39 75 10 80 push $0x80107539 +80101e97: e8 f4 e4 ff ff call 80100390 + panic("dirlookup not DIR"); +80101e9c: 83 ec 0c sub $0xc,%esp +80101e9f: 68 27 75 10 80 push $0x80107527 +80101ea4: e8 e7 e4 ff ff call 80100390 +80101ea9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80101eb0 : + +// Look up and return the inode for a path name. +// If parent != 0, return the inode for the parent and copy the final +// path element into name, which must have room for DIRSIZ bytes. +// Must be called inside a transaction since it calls iput(). +static struct inode* namex(char *path, int nameiparent, char *name) { +80101eb0: 55 push %ebp +80101eb1: 89 e5 mov %esp,%ebp +80101eb3: 57 push %edi +80101eb4: 56 push %esi +80101eb5: 53 push %ebx +80101eb6: 89 c3 mov %eax,%ebx +80101eb8: 83 ec 1c sub $0x1c,%esp + struct inode *ip, *next; + + if (*path == '/') { +80101ebb: 80 38 2f cmpb $0x2f,(%eax) +static struct inode* namex(char *path, int nameiparent, char *name) { +80101ebe: 89 55 dc mov %edx,-0x24(%ebp) +80101ec1: 89 4d e4 mov %ecx,-0x1c(%ebp) + if (*path == '/') { +80101ec4: 0f 84 64 01 00 00 je 8010202e + ip = iget(ROOTDEV, ROOTINO); + } + else { + ip = idup(myproc()->cwd); +80101eca: e8 01 1c 00 00 call 80103ad0 + acquire(&icache.lock); +80101ecf: 83 ec 0c sub $0xc,%esp + ip = idup(myproc()->cwd); +80101ed2: 8b 70 68 mov 0x68(%eax),%esi + acquire(&icache.lock); +80101ed5: 68 80 f9 10 80 push $0x8010f980 +80101eda: e8 21 28 00 00 call 80104700 + ip->ref++; +80101edf: 83 46 08 01 addl $0x1,0x8(%esi) + release(&icache.lock); +80101ee3: c7 04 24 80 f9 10 80 movl $0x8010f980,(%esp) +80101eea: e8 b1 27 00 00 call 801046a0 +80101eef: 83 c4 10 add $0x10,%esp +80101ef2: eb 07 jmp 80101efb +80101ef4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + path++; +80101ef8: 83 c3 01 add $0x1,%ebx + while (*path == '/') { +80101efb: 0f b6 03 movzbl (%ebx),%eax +80101efe: 3c 2f cmp $0x2f,%al +80101f00: 74 f6 je 80101ef8 + if (*path == 0) { +80101f02: 84 c0 test %al,%al +80101f04: 0f 84 06 01 00 00 je 80102010 + while (*path != '/' && *path != 0) { +80101f0a: 0f b6 03 movzbl (%ebx),%eax +80101f0d: 84 c0 test %al,%al +80101f0f: 0f 84 10 01 00 00 je 80102025 +80101f15: 89 df mov %ebx,%edi +80101f17: 3c 2f cmp $0x2f,%al +80101f19: 0f 84 06 01 00 00 je 80102025 +80101f1f: 90 nop +80101f20: 0f b6 47 01 movzbl 0x1(%edi),%eax + path++; +80101f24: 83 c7 01 add $0x1,%edi + while (*path != '/' && *path != 0) { +80101f27: 3c 2f cmp $0x2f,%al +80101f29: 74 04 je 80101f2f +80101f2b: 84 c0 test %al,%al +80101f2d: 75 f1 jne 80101f20 + len = path - s; +80101f2f: 89 f8 mov %edi,%eax +80101f31: 29 d8 sub %ebx,%eax + if (len >= DIRSIZ) { +80101f33: 83 f8 0d cmp $0xd,%eax +80101f36: 0f 8e ac 00 00 00 jle 80101fe8 + memmove(name, s, DIRSIZ); +80101f3c: 83 ec 04 sub $0x4,%esp +80101f3f: 6a 0e push $0xe +80101f41: 53 push %ebx + path++; +80101f42: 89 fb mov %edi,%ebx + memmove(name, s, DIRSIZ); +80101f44: ff 75 e4 push -0x1c(%ebp) +80101f47: e8 14 29 00 00 call 80104860 +80101f4c: 83 c4 10 add $0x10,%esp + while (*path == '/') { +80101f4f: 80 3f 2f cmpb $0x2f,(%edi) +80101f52: 75 0c jne 80101f60 +80101f54: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + path++; +80101f58: 83 c3 01 add $0x1,%ebx + while (*path == '/') { +80101f5b: 80 3b 2f cmpb $0x2f,(%ebx) +80101f5e: 74 f8 je 80101f58 + } + + while ((path = skipelem(path, name)) != 0) { + ilock(ip); +80101f60: 83 ec 0c sub $0xc,%esp +80101f63: 56 push %esi +80101f64: e8 37 f9 ff ff call 801018a0 + if (ip->type != T_DIR) { +80101f69: 83 c4 10 add $0x10,%esp +80101f6c: 66 83 7e 50 01 cmpw $0x1,0x50(%esi) +80101f71: 0f 85 cd 00 00 00 jne 80102044 + iunlockput(ip); + return 0; + } + if (nameiparent && *path == '\0') { +80101f77: 8b 45 dc mov -0x24(%ebp),%eax +80101f7a: 85 c0 test %eax,%eax +80101f7c: 74 09 je 80101f87 +80101f7e: 80 3b 00 cmpb $0x0,(%ebx) +80101f81: 0f 84 22 01 00 00 je 801020a9 + // Stop one level early. + iunlock(ip); + return ip; + } + if ((next = dirlookup(ip, name, 0)) == 0) { +80101f87: 83 ec 04 sub $0x4,%esp +80101f8a: 6a 00 push $0x0 +80101f8c: ff 75 e4 push -0x1c(%ebp) +80101f8f: 56 push %esi +80101f90: e8 6b fe ff ff call 80101e00 + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { +80101f95: 8d 56 0c lea 0xc(%esi),%edx + if ((next = dirlookup(ip, name, 0)) == 0) { +80101f98: 83 c4 10 add $0x10,%esp +80101f9b: 89 c7 mov %eax,%edi +80101f9d: 85 c0 test %eax,%eax +80101f9f: 0f 84 e1 00 00 00 je 80102086 + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { +80101fa5: 83 ec 0c sub $0xc,%esp +80101fa8: 89 55 e0 mov %edx,-0x20(%ebp) +80101fab: 52 push %edx +80101fac: e8 2f 25 00 00 call 801044e0 +80101fb1: 83 c4 10 add $0x10,%esp +80101fb4: 85 c0 test %eax,%eax +80101fb6: 0f 84 30 01 00 00 je 801020ec +80101fbc: 8b 56 08 mov 0x8(%esi),%edx +80101fbf: 85 d2 test %edx,%edx +80101fc1: 0f 8e 25 01 00 00 jle 801020ec + releasesleep(&ip->lock); +80101fc7: 8b 55 e0 mov -0x20(%ebp),%edx +80101fca: 83 ec 0c sub $0xc,%esp +80101fcd: 52 push %edx +80101fce: e8 cd 24 00 00 call 801044a0 + iput(ip); +80101fd3: 89 34 24 mov %esi,(%esp) +80101fd6: 89 fe mov %edi,%esi +80101fd8: e8 f3 f9 ff ff call 801019d0 +80101fdd: 83 c4 10 add $0x10,%esp +80101fe0: e9 16 ff ff ff jmp 80101efb +80101fe5: 8d 76 00 lea 0x0(%esi),%esi + name[len] = 0; +80101fe8: 8b 4d e4 mov -0x1c(%ebp),%ecx +80101feb: 8d 14 01 lea (%ecx,%eax,1),%edx + memmove(name, s, len); +80101fee: 83 ec 04 sub $0x4,%esp +80101ff1: 89 55 e0 mov %edx,-0x20(%ebp) +80101ff4: 50 push %eax +80101ff5: 53 push %ebx + name[len] = 0; +80101ff6: 89 fb mov %edi,%ebx + memmove(name, s, len); +80101ff8: ff 75 e4 push -0x1c(%ebp) +80101ffb: e8 60 28 00 00 call 80104860 + name[len] = 0; +80102000: 8b 55 e0 mov -0x20(%ebp),%edx +80102003: 83 c4 10 add $0x10,%esp +80102006: c6 02 00 movb $0x0,(%edx) +80102009: e9 41 ff ff ff jmp 80101f4f +8010200e: 66 90 xchg %ax,%ax + return 0; + } + iunlockput(ip); + ip = next; + } + if (nameiparent) { +80102010: 8b 45 dc mov -0x24(%ebp),%eax +80102013: 85 c0 test %eax,%eax +80102015: 0f 85 be 00 00 00 jne 801020d9 + iput(ip); + return 0; + } + return ip; +} +8010201b: 8d 65 f4 lea -0xc(%ebp),%esp +8010201e: 89 f0 mov %esi,%eax +80102020: 5b pop %ebx +80102021: 5e pop %esi +80102022: 5f pop %edi +80102023: 5d pop %ebp +80102024: c3 ret + while (*path != '/' && *path != 0) { +80102025: 8b 55 e4 mov -0x1c(%ebp),%edx +80102028: 89 df mov %ebx,%edi +8010202a: 31 c0 xor %eax,%eax +8010202c: eb c0 jmp 80101fee + ip = iget(ROOTDEV, ROOTINO); +8010202e: ba 01 00 00 00 mov $0x1,%edx +80102033: b8 01 00 00 00 mov $0x1,%eax +80102038: e8 33 f4 ff ff call 80101470 +8010203d: 89 c6 mov %eax,%esi +8010203f: e9 b7 fe ff ff jmp 80101efb + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { +80102044: 83 ec 0c sub $0xc,%esp +80102047: 8d 5e 0c lea 0xc(%esi),%ebx +8010204a: 53 push %ebx +8010204b: e8 90 24 00 00 call 801044e0 +80102050: 83 c4 10 add $0x10,%esp +80102053: 85 c0 test %eax,%eax +80102055: 0f 84 91 00 00 00 je 801020ec +8010205b: 8b 46 08 mov 0x8(%esi),%eax +8010205e: 85 c0 test %eax,%eax +80102060: 0f 8e 86 00 00 00 jle 801020ec + releasesleep(&ip->lock); +80102066: 83 ec 0c sub $0xc,%esp +80102069: 53 push %ebx +8010206a: e8 31 24 00 00 call 801044a0 + iput(ip); +8010206f: 89 34 24 mov %esi,(%esp) + return 0; +80102072: 31 f6 xor %esi,%esi + iput(ip); +80102074: e8 57 f9 ff ff call 801019d0 + return 0; +80102079: 83 c4 10 add $0x10,%esp +} +8010207c: 8d 65 f4 lea -0xc(%ebp),%esp +8010207f: 89 f0 mov %esi,%eax +80102081: 5b pop %ebx +80102082: 5e pop %esi +80102083: 5f pop %edi +80102084: 5d pop %ebp +80102085: c3 ret + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { +80102086: 83 ec 0c sub $0xc,%esp +80102089: 89 55 e4 mov %edx,-0x1c(%ebp) +8010208c: 52 push %edx +8010208d: e8 4e 24 00 00 call 801044e0 +80102092: 83 c4 10 add $0x10,%esp +80102095: 85 c0 test %eax,%eax +80102097: 74 53 je 801020ec +80102099: 8b 4e 08 mov 0x8(%esi),%ecx +8010209c: 85 c9 test %ecx,%ecx +8010209e: 7e 4c jle 801020ec + releasesleep(&ip->lock); +801020a0: 8b 55 e4 mov -0x1c(%ebp),%edx +801020a3: 83 ec 0c sub $0xc,%esp +801020a6: 52 push %edx +801020a7: eb c1 jmp 8010206a + if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) { +801020a9: 83 ec 0c sub $0xc,%esp +801020ac: 8d 5e 0c lea 0xc(%esi),%ebx +801020af: 53 push %ebx +801020b0: e8 2b 24 00 00 call 801044e0 +801020b5: 83 c4 10 add $0x10,%esp +801020b8: 85 c0 test %eax,%eax +801020ba: 74 30 je 801020ec +801020bc: 8b 7e 08 mov 0x8(%esi),%edi +801020bf: 85 ff test %edi,%edi +801020c1: 7e 29 jle 801020ec + releasesleep(&ip->lock); +801020c3: 83 ec 0c sub $0xc,%esp +801020c6: 53 push %ebx +801020c7: e8 d4 23 00 00 call 801044a0 +} +801020cc: 83 c4 10 add $0x10,%esp +} +801020cf: 8d 65 f4 lea -0xc(%ebp),%esp +801020d2: 89 f0 mov %esi,%eax +801020d4: 5b pop %ebx +801020d5: 5e pop %esi +801020d6: 5f pop %edi +801020d7: 5d pop %ebp +801020d8: c3 ret + iput(ip); +801020d9: 83 ec 0c sub $0xc,%esp +801020dc: 56 push %esi + return 0; +801020dd: 31 f6 xor %esi,%esi + iput(ip); +801020df: e8 ec f8 ff ff call 801019d0 + return 0; +801020e4: 83 c4 10 add $0x10,%esp +801020e7: e9 2f ff ff ff jmp 8010201b + panic("iunlock"); +801020ec: 83 ec 0c sub $0xc,%esp +801020ef: 68 1f 75 10 80 push $0x8010751f +801020f4: e8 97 e2 ff ff call 80100390 +801020f9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80102100 : +int dirlink(struct inode *dp, char *name, uint inum) { +80102100: 55 push %ebp +80102101: 89 e5 mov %esp,%ebp +80102103: 57 push %edi +80102104: 56 push %esi +80102105: 53 push %ebx +80102106: 83 ec 20 sub $0x20,%esp +80102109: 8b 5d 08 mov 0x8(%ebp),%ebx + if ((ip = dirlookup(dp, name, 0)) != 0) { +8010210c: 6a 00 push $0x0 +8010210e: ff 75 0c push 0xc(%ebp) +80102111: 53 push %ebx +80102112: e8 e9 fc ff ff call 80101e00 +80102117: 83 c4 10 add $0x10,%esp +8010211a: 85 c0 test %eax,%eax +8010211c: 75 67 jne 80102185 + for (off = 0; off < dp->size; off += sizeof(de)) { +8010211e: 8b 7b 58 mov 0x58(%ebx),%edi +80102121: 8d 75 d8 lea -0x28(%ebp),%esi +80102124: 85 ff test %edi,%edi +80102126: 74 29 je 80102151 +80102128: 31 ff xor %edi,%edi +8010212a: 8d 75 d8 lea -0x28(%ebp),%esi +8010212d: eb 09 jmp 80102138 +8010212f: 90 nop +80102130: 83 c7 10 add $0x10,%edi +80102133: 3b 7b 58 cmp 0x58(%ebx),%edi +80102136: 73 19 jae 80102151 + if (readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { +80102138: 6a 10 push $0x10 +8010213a: 57 push %edi +8010213b: 56 push %esi +8010213c: 53 push %ebx +8010213d: e8 6e fa ff ff call 80101bb0 +80102142: 83 c4 10 add $0x10,%esp +80102145: 83 f8 10 cmp $0x10,%eax +80102148: 75 4e jne 80102198 + if (de.inum == 0) { +8010214a: 66 83 7d d8 00 cmpw $0x0,-0x28(%ebp) +8010214f: 75 df jne 80102130 + strncpy(de.name, name, DIRSIZ); +80102151: 83 ec 04 sub $0x4,%esp +80102154: 8d 45 da lea -0x26(%ebp),%eax +80102157: 6a 0e push $0xe +80102159: ff 75 0c push 0xc(%ebp) +8010215c: 50 push %eax +8010215d: e8 be 27 00 00 call 80104920 + if (writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { +80102162: 6a 10 push $0x10 + de.inum = inum; +80102164: 8b 45 10 mov 0x10(%ebp),%eax + if (writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { +80102167: 57 push %edi +80102168: 56 push %esi +80102169: 53 push %ebx + de.inum = inum; +8010216a: 66 89 45 d8 mov %ax,-0x28(%ebp) + if (writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { +8010216e: e8 3d fb ff ff call 80101cb0 +80102173: 83 c4 20 add $0x20,%esp +80102176: 83 f8 10 cmp $0x10,%eax +80102179: 75 2a jne 801021a5 + return 0; +8010217b: 31 c0 xor %eax,%eax +} +8010217d: 8d 65 f4 lea -0xc(%ebp),%esp +80102180: 5b pop %ebx +80102181: 5e pop %esi +80102182: 5f pop %edi +80102183: 5d pop %ebp +80102184: c3 ret + iput(ip); +80102185: 83 ec 0c sub $0xc,%esp +80102188: 50 push %eax +80102189: e8 42 f8 ff ff call 801019d0 + return -1; +8010218e: 83 c4 10 add $0x10,%esp +80102191: b8 ff ff ff ff mov $0xffffffff,%eax +80102196: eb e5 jmp 8010217d + panic("dirlink read"); +80102198: 83 ec 0c sub $0xc,%esp +8010219b: 68 48 75 10 80 push $0x80107548 +801021a0: e8 eb e1 ff ff call 80100390 + panic("dirlink"); +801021a5: 83 ec 0c sub $0xc,%esp +801021a8: 68 2a 7b 10 80 push $0x80107b2a +801021ad: e8 de e1 ff ff call 80100390 +801021b2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801021b9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +801021c0 : + +struct inode* namei(char *path) { +801021c0: 55 push %ebp + char name[DIRSIZ]; + return namex(path, 0, name); +801021c1: 31 d2 xor %edx,%edx +struct inode* namei(char *path) { +801021c3: 89 e5 mov %esp,%ebp +801021c5: 83 ec 18 sub $0x18,%esp + return namex(path, 0, name); +801021c8: 8b 45 08 mov 0x8(%ebp),%eax +801021cb: 8d 4d ea lea -0x16(%ebp),%ecx +801021ce: e8 dd fc ff ff call 80101eb0 +} +801021d3: c9 leave +801021d4: c3 ret +801021d5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801021dc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +801021e0 : + +struct inode*nameiparent(char *path, char *name) { +801021e0: 55 push %ebp + return namex(path, 1, name); +801021e1: ba 01 00 00 00 mov $0x1,%edx +struct inode*nameiparent(char *path, char *name) { +801021e6: 89 e5 mov %esp,%ebp + return namex(path, 1, name); +801021e8: 8b 4d 0c mov 0xc(%ebp),%ecx +801021eb: 8b 45 08 mov 0x8(%ebp),%eax +} +801021ee: 5d pop %ebp + return namex(path, 1, name); +801021ef: e9 bc fc ff ff jmp 80101eb0 +801021f4: 66 90 xchg %ax,%ax +801021f6: 66 90 xchg %ax,%ax +801021f8: 66 90 xchg %ax,%ax +801021fa: 66 90 xchg %ax,%ax +801021fc: 66 90 xchg %ax,%ax +801021fe: 66 90 xchg %ax,%ax + +80102200 : + // Switch back to disk 0. + outb(0x1f6, 0xe0 | (0 << 4)); +} + +// Start the request for b. Caller must hold idelock. +static void idestart(struct buf *b) { +80102200: 55 push %ebp +80102201: 89 e5 mov %esp,%ebp +80102203: 57 push %edi +80102204: 56 push %esi +80102205: 53 push %ebx +80102206: 83 ec 0c sub $0xc,%esp + if (b == 0) { +80102209: 85 c0 test %eax,%eax +8010220b: 0f 84 b4 00 00 00 je 801022c5 + panic("idestart"); + } + if (b->blockno >= FSSIZE) { +80102211: 8b 70 08 mov 0x8(%eax),%esi +80102214: 89 c3 mov %eax,%ebx +80102216: 81 fe e7 03 00 00 cmp $0x3e7,%esi +8010221c: 0f 87 96 00 00 00 ja 801022b8 + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102222: b9 f7 01 00 00 mov $0x1f7,%ecx +80102227: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010222e: 66 90 xchg %ax,%ax +80102230: 89 ca mov %ecx,%edx +80102232: ec in (%dx),%al + while (((r = inb(0x1f7)) & (IDE_BSY | IDE_DRDY)) != IDE_DRDY) { +80102233: 83 e0 c0 and $0xffffffc0,%eax +80102236: 3c 40 cmp $0x40,%al +80102238: 75 f6 jne 80102230 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +8010223a: 31 ff xor %edi,%edi +8010223c: ba f6 03 00 00 mov $0x3f6,%edx +80102241: 89 f8 mov %edi,%eax +80102243: ee out %al,(%dx) +80102244: b8 01 00 00 00 mov $0x1,%eax +80102249: ba f2 01 00 00 mov $0x1f2,%edx +8010224e: ee out %al,(%dx) +8010224f: ba f3 01 00 00 mov $0x1f3,%edx +80102254: 89 f0 mov %esi,%eax +80102256: ee out %al,(%dx) + + idewait(0); + outb(0x3f6, 0); // generate interrupt + outb(0x1f2, sector_per_block); // number of sectors + outb(0x1f3, sector & 0xff); + outb(0x1f4, (sector >> 8) & 0xff); +80102257: 89 f0 mov %esi,%eax +80102259: ba f4 01 00 00 mov $0x1f4,%edx +8010225e: c1 f8 08 sar $0x8,%eax +80102261: ee out %al,(%dx) +80102262: ba f5 01 00 00 mov $0x1f5,%edx +80102267: 89 f8 mov %edi,%eax +80102269: ee out %al,(%dx) + outb(0x1f5, (sector >> 16) & 0xff); + outb(0x1f6, 0xe0 | ((b->dev & 1) << 4) | ((sector >> 24) & 0x0f)); +8010226a: 0f b6 43 04 movzbl 0x4(%ebx),%eax +8010226e: ba f6 01 00 00 mov $0x1f6,%edx +80102273: c1 e0 04 shl $0x4,%eax +80102276: 83 e0 10 and $0x10,%eax +80102279: 83 c8 e0 or $0xffffffe0,%eax +8010227c: ee out %al,(%dx) + if (b->flags & B_DIRTY) { +8010227d: f6 03 04 testb $0x4,(%ebx) +80102280: 75 16 jne 80102298 +80102282: b8 20 00 00 00 mov $0x20,%eax +80102287: 89 ca mov %ecx,%edx +80102289: ee out %al,(%dx) + outsl(0x1f0, b->data, BSIZE / 4); + } + else { + outb(0x1f7, read_cmd); + } +} +8010228a: 8d 65 f4 lea -0xc(%ebp),%esp +8010228d: 5b pop %ebx +8010228e: 5e pop %esi +8010228f: 5f pop %edi +80102290: 5d pop %ebp +80102291: c3 ret +80102292: 8d b6 00 00 00 00 lea 0x0(%esi),%esi +80102298: b8 30 00 00 00 mov $0x30,%eax +8010229d: 89 ca mov %ecx,%edx +8010229f: ee out %al,(%dx) + asm volatile ("cld; rep outsl" : +801022a0: b9 80 00 00 00 mov $0x80,%ecx + outsl(0x1f0, b->data, BSIZE / 4); +801022a5: 8d 73 5c lea 0x5c(%ebx),%esi +801022a8: ba f0 01 00 00 mov $0x1f0,%edx +801022ad: fc cld +801022ae: f3 6f rep outsl %ds:(%esi),(%dx) +} +801022b0: 8d 65 f4 lea -0xc(%ebp),%esp +801022b3: 5b pop %ebx +801022b4: 5e pop %esi +801022b5: 5f pop %edi +801022b6: 5d pop %ebp +801022b7: c3 ret + panic("incorrect blockno"); +801022b8: 83 ec 0c sub $0xc,%esp +801022bb: 68 b4 75 10 80 push $0x801075b4 +801022c0: e8 cb e0 ff ff call 80100390 + panic("idestart"); +801022c5: 83 ec 0c sub $0xc,%esp +801022c8: 68 ab 75 10 80 push $0x801075ab +801022cd: e8 be e0 ff ff call 80100390 +801022d2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801022d9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +801022e0 : +void ideinit(void) { +801022e0: 55 push %ebp +801022e1: 89 e5 mov %esp,%ebp +801022e3: 83 ec 10 sub $0x10,%esp + initlock(&idelock, "ide"); +801022e6: 68 c6 75 10 80 push $0x801075c6 +801022eb: 68 20 16 11 80 push $0x80111620 +801022f0: e8 3b 22 00 00 call 80104530 + ioapicenable(IRQ_IDE, ncpu - 1); +801022f5: 58 pop %eax +801022f6: a1 a4 17 11 80 mov 0x801117a4,%eax +801022fb: 5a pop %edx +801022fc: 83 e8 01 sub $0x1,%eax +801022ff: 50 push %eax +80102300: 6a 0e push $0xe +80102302: e8 99 02 00 00 call 801025a0 + while (((r = inb(0x1f7)) & (IDE_BSY | IDE_DRDY)) != IDE_DRDY) { +80102307: 83 c4 10 add $0x10,%esp + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +8010230a: ba f7 01 00 00 mov $0x1f7,%edx +8010230f: 90 nop +80102310: ec in (%dx),%al +80102311: 83 e0 c0 and $0xffffffc0,%eax +80102314: 3c 40 cmp $0x40,%al +80102316: 75 f8 jne 80102310 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102318: b8 f0 ff ff ff mov $0xfffffff0,%eax +8010231d: ba f6 01 00 00 mov $0x1f6,%edx +80102322: ee out %al,(%dx) +80102323: b9 e8 03 00 00 mov $0x3e8,%ecx + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102328: ba f7 01 00 00 mov $0x1f7,%edx +8010232d: eb 06 jmp 80102335 +8010232f: 90 nop + for (i = 0; i < 1000; i++) { +80102330: 83 e9 01 sub $0x1,%ecx +80102333: 74 0f je 80102344 +80102335: ec in (%dx),%al + if (inb(0x1f7) != 0) { +80102336: 84 c0 test %al,%al +80102338: 74 f6 je 80102330 + havedisk1 = 1; +8010233a: c7 05 00 16 11 80 01 movl $0x1,0x80111600 +80102341: 00 00 00 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102344: b8 e0 ff ff ff mov $0xffffffe0,%eax +80102349: ba f6 01 00 00 mov $0x1f6,%edx +8010234e: ee out %al,(%dx) +} +8010234f: c9 leave +80102350: c3 ret +80102351: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102358: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010235f: 90 nop + +80102360 : + +// Interrupt handler. +void ideintr(void) { +80102360: 55 push %ebp +80102361: 89 e5 mov %esp,%ebp +80102363: 57 push %edi +80102364: 56 push %esi +80102365: 53 push %ebx +80102366: 83 ec 18 sub $0x18,%esp + struct buf *b; + + // First queued buffer is the active request. + acquire(&idelock); +80102369: 68 20 16 11 80 push $0x80111620 +8010236e: e8 8d 23 00 00 call 80104700 + + if ((b = idequeue) == 0) { +80102373: 8b 1d 04 16 11 80 mov 0x80111604,%ebx +80102379: 83 c4 10 add $0x10,%esp +8010237c: 85 db test %ebx,%ebx +8010237e: 74 63 je 801023e3 + release(&idelock); + return; + } + idequeue = b->qnext; +80102380: 8b 43 58 mov 0x58(%ebx),%eax +80102383: a3 04 16 11 80 mov %eax,0x80111604 + + // Read data if needed. + if (!(b->flags & B_DIRTY) && idewait(1) >= 0) { +80102388: 8b 33 mov (%ebx),%esi +8010238a: f7 c6 04 00 00 00 test $0x4,%esi +80102390: 75 2f jne 801023c1 + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102392: ba f7 01 00 00 mov $0x1f7,%edx +80102397: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010239e: 66 90 xchg %ax,%ax +801023a0: ec in (%dx),%al + while (((r = inb(0x1f7)) & (IDE_BSY | IDE_DRDY)) != IDE_DRDY) { +801023a1: 89 c1 mov %eax,%ecx +801023a3: 83 e1 c0 and $0xffffffc0,%ecx +801023a6: 80 f9 40 cmp $0x40,%cl +801023a9: 75 f5 jne 801023a0 + if (checkerr && (r & (IDE_DF | IDE_ERR)) != 0) { +801023ab: a8 21 test $0x21,%al +801023ad: 75 12 jne 801023c1 + insl(0x1f0, b->data, BSIZE / 4); +801023af: 8d 7b 5c lea 0x5c(%ebx),%edi + asm volatile ("cld; rep insl" : +801023b2: b9 80 00 00 00 mov $0x80,%ecx +801023b7: ba f0 01 00 00 mov $0x1f0,%edx +801023bc: fc cld +801023bd: f3 6d rep insl (%dx),%es:(%edi) + } + + // Wake process waiting for this buf. + b->flags |= B_VALID; +801023bf: 8b 33 mov (%ebx),%esi + b->flags &= ~B_DIRTY; +801023c1: 83 e6 fb and $0xfffffffb,%esi + wakeup(b); +801023c4: 83 ec 0c sub $0xc,%esp + b->flags &= ~B_DIRTY; +801023c7: 83 ce 02 or $0x2,%esi +801023ca: 89 33 mov %esi,(%ebx) + wakeup(b); +801023cc: 53 push %ebx +801023cd: e8 8e 1e 00 00 call 80104260 + + // Start disk on next buf in queue. + if (idequeue != 0) { +801023d2: a1 04 16 11 80 mov 0x80111604,%eax +801023d7: 83 c4 10 add $0x10,%esp +801023da: 85 c0 test %eax,%eax +801023dc: 74 05 je 801023e3 + idestart(idequeue); +801023de: e8 1d fe ff ff call 80102200 + release(&idelock); +801023e3: 83 ec 0c sub $0xc,%esp +801023e6: 68 20 16 11 80 push $0x80111620 +801023eb: e8 b0 22 00 00 call 801046a0 + } + + release(&idelock); +} +801023f0: 8d 65 f4 lea -0xc(%ebp),%esp +801023f3: 5b pop %ebx +801023f4: 5e pop %esi +801023f5: 5f pop %edi +801023f6: 5d pop %ebp +801023f7: c3 ret +801023f8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801023ff: 90 nop + +80102400 : + + +// Sync buf with disk. +// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID. +// Else if B_VALID is not set, read buf from disk, set B_VALID. +void iderw(struct buf *b) { +80102400: 55 push %ebp +80102401: 89 e5 mov %esp,%ebp +80102403: 53 push %ebx +80102404: 83 ec 10 sub $0x10,%esp +80102407: 8b 5d 08 mov 0x8(%ebp),%ebx + struct buf **pp; + + if (!holdingsleep(&b->lock)) { +8010240a: 8d 43 0c lea 0xc(%ebx),%eax +8010240d: 50 push %eax +8010240e: e8 cd 20 00 00 call 801044e0 +80102413: 83 c4 10 add $0x10,%esp +80102416: 85 c0 test %eax,%eax +80102418: 0f 84 c3 00 00 00 je 801024e1 + panic("iderw: buf not locked"); + } + if ((b->flags & (B_VALID | B_DIRTY)) == B_VALID) { +8010241e: 8b 03 mov (%ebx),%eax +80102420: 83 e0 06 and $0x6,%eax +80102423: 83 f8 02 cmp $0x2,%eax +80102426: 0f 84 a8 00 00 00 je 801024d4 + panic("iderw: nothing to do"); + } + if (b->dev != 0 && !havedisk1) { +8010242c: 8b 53 04 mov 0x4(%ebx),%edx +8010242f: 85 d2 test %edx,%edx +80102431: 74 0d je 80102440 +80102433: a1 00 16 11 80 mov 0x80111600,%eax +80102438: 85 c0 test %eax,%eax +8010243a: 0f 84 87 00 00 00 je 801024c7 + panic("iderw: ide disk 1 not present"); + } + + acquire(&idelock); //DOC:acquire-lock +80102440: 83 ec 0c sub $0xc,%esp +80102443: 68 20 16 11 80 push $0x80111620 +80102448: e8 b3 22 00 00 call 80104700 + + // Append b to idequeue. + b->qnext = 0; + for (pp = &idequeue; *pp; pp = &(*pp)->qnext) { //DOC:insert-queue +8010244d: a1 04 16 11 80 mov 0x80111604,%eax + b->qnext = 0; +80102452: c7 43 58 00 00 00 00 movl $0x0,0x58(%ebx) + for (pp = &idequeue; *pp; pp = &(*pp)->qnext) { //DOC:insert-queue +80102459: 83 c4 10 add $0x10,%esp +8010245c: 85 c0 test %eax,%eax +8010245e: 74 60 je 801024c0 +80102460: 89 c2 mov %eax,%edx +80102462: 8b 40 58 mov 0x58(%eax),%eax +80102465: 85 c0 test %eax,%eax +80102467: 75 f7 jne 80102460 +80102469: 83 c2 58 add $0x58,%edx + ; + } + *pp = b; +8010246c: 89 1a mov %ebx,(%edx) + + // Start disk if necessary. + if (idequeue == b) { +8010246e: 39 1d 04 16 11 80 cmp %ebx,0x80111604 +80102474: 74 3a je 801024b0 + idestart(b); + } + + // Wait for request to finish. + while ((b->flags & (B_VALID | B_DIRTY)) != B_VALID) { +80102476: 8b 03 mov (%ebx),%eax +80102478: 83 e0 06 and $0x6,%eax +8010247b: 83 f8 02 cmp $0x2,%eax +8010247e: 74 1b je 8010249b + sleep(b, &idelock); +80102480: 83 ec 08 sub $0x8,%esp +80102483: 68 20 16 11 80 push $0x80111620 +80102488: 53 push %ebx +80102489: e8 12 1d 00 00 call 801041a0 + while ((b->flags & (B_VALID | B_DIRTY)) != B_VALID) { +8010248e: 8b 03 mov (%ebx),%eax +80102490: 83 c4 10 add $0x10,%esp +80102493: 83 e0 06 and $0x6,%eax +80102496: 83 f8 02 cmp $0x2,%eax +80102499: 75 e5 jne 80102480 + } + + release(&idelock); +8010249b: c7 45 08 20 16 11 80 movl $0x80111620,0x8(%ebp) +} +801024a2: 8b 5d fc mov -0x4(%ebp),%ebx +801024a5: c9 leave + release(&idelock); +801024a6: e9 f5 21 00 00 jmp 801046a0 +801024ab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801024af: 90 nop + idestart(b); +801024b0: 89 d8 mov %ebx,%eax +801024b2: e8 49 fd ff ff call 80102200 +801024b7: eb bd jmp 80102476 +801024b9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + for (pp = &idequeue; *pp; pp = &(*pp)->qnext) { //DOC:insert-queue +801024c0: ba 04 16 11 80 mov $0x80111604,%edx +801024c5: eb a5 jmp 8010246c + panic("iderw: ide disk 1 not present"); +801024c7: 83 ec 0c sub $0xc,%esp +801024ca: 68 f5 75 10 80 push $0x801075f5 +801024cf: e8 bc de ff ff call 80100390 + panic("iderw: nothing to do"); +801024d4: 83 ec 0c sub $0xc,%esp +801024d7: 68 e0 75 10 80 push $0x801075e0 +801024dc: e8 af de ff ff call 80100390 + panic("iderw: buf not locked"); +801024e1: 83 ec 0c sub $0xc,%esp +801024e4: 68 ca 75 10 80 push $0x801075ca +801024e9: e8 a2 de ff ff call 80100390 +801024ee: 66 90 xchg %ax,%ax + +801024f0 : +static void ioapicwrite(int reg, uint data) { + ioapic->reg = reg; + ioapic->data = data; +} + +void ioapicinit(void) { +801024f0: 55 push %ebp + int i, id, maxintr; + + ioapic = (volatile struct ioapic*)IOAPIC; +801024f1: c7 05 54 16 11 80 00 movl $0xfec00000,0x80111654 +801024f8: 00 c0 fe +void ioapicinit(void) { +801024fb: 89 e5 mov %esp,%ebp +801024fd: 56 push %esi +801024fe: 53 push %ebx + ioapic->reg = reg; +801024ff: c7 05 00 00 c0 fe 01 movl $0x1,0xfec00000 +80102506: 00 00 00 + return ioapic->data; +80102509: 8b 15 54 16 11 80 mov 0x80111654,%edx +8010250f: 8b 72 10 mov 0x10(%edx),%esi + ioapic->reg = reg; +80102512: c7 02 00 00 00 00 movl $0x0,(%edx) + return ioapic->data; +80102518: 8b 0d 54 16 11 80 mov 0x80111654,%ecx + maxintr = (ioapicread(REG_VER) >> 16) & 0xFF; + id = ioapicread(REG_ID) >> 24; + if (id != ioapicid) { +8010251e: 0f b6 15 a0 17 11 80 movzbl 0x801117a0,%edx + maxintr = (ioapicread(REG_VER) >> 16) & 0xFF; +80102525: c1 ee 10 shr $0x10,%esi +80102528: 89 f0 mov %esi,%eax +8010252a: 0f b6 f0 movzbl %al,%esi + return ioapic->data; +8010252d: 8b 41 10 mov 0x10(%ecx),%eax + id = ioapicread(REG_ID) >> 24; +80102530: c1 e8 18 shr $0x18,%eax + if (id != ioapicid) { +80102533: 39 c2 cmp %eax,%edx +80102535: 74 16 je 8010254d + cprintf("ioapicinit: id isn't equal to ioapicid; not a MP\n"); +80102537: 83 ec 0c sub $0xc,%esp +8010253a: 68 14 76 10 80 push $0x80107614 +8010253f: e8 6c e1 ff ff call 801006b0 + ioapic->reg = reg; +80102544: 8b 0d 54 16 11 80 mov 0x80111654,%ecx +8010254a: 83 c4 10 add $0x10,%esp +8010254d: 83 c6 21 add $0x21,%esi +void ioapicinit(void) { +80102550: ba 10 00 00 00 mov $0x10,%edx +80102555: b8 20 00 00 00 mov $0x20,%eax +8010255a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + ioapic->reg = reg; +80102560: 89 11 mov %edx,(%ecx) + } + + // Mark all interrupts edge-triggered, active high, disabled, + // and not routed to any CPUs. + for (i = 0; i <= maxintr; i++) { + ioapicwrite(REG_TABLE + 2 * i, INT_DISABLED | (T_IRQ0 + i)); +80102562: 89 c3 mov %eax,%ebx + ioapic->data = data; +80102564: 8b 0d 54 16 11 80 mov 0x80111654,%ecx + for (i = 0; i <= maxintr; i++) { +8010256a: 83 c0 01 add $0x1,%eax + ioapicwrite(REG_TABLE + 2 * i, INT_DISABLED | (T_IRQ0 + i)); +8010256d: 81 cb 00 00 01 00 or $0x10000,%ebx + ioapic->data = data; +80102573: 89 59 10 mov %ebx,0x10(%ecx) + ioapic->reg = reg; +80102576: 8d 5a 01 lea 0x1(%edx),%ebx + for (i = 0; i <= maxintr; i++) { +80102579: 83 c2 02 add $0x2,%edx + ioapic->reg = reg; +8010257c: 89 19 mov %ebx,(%ecx) + ioapic->data = data; +8010257e: 8b 0d 54 16 11 80 mov 0x80111654,%ecx +80102584: c7 41 10 00 00 00 00 movl $0x0,0x10(%ecx) + for (i = 0; i <= maxintr; i++) { +8010258b: 39 f0 cmp %esi,%eax +8010258d: 75 d1 jne 80102560 + ioapicwrite(REG_TABLE + 2 * i + 1, 0); + } +} +8010258f: 8d 65 f8 lea -0x8(%ebp),%esp +80102592: 5b pop %ebx +80102593: 5e pop %esi +80102594: 5d pop %ebp +80102595: c3 ret +80102596: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010259d: 8d 76 00 lea 0x0(%esi),%esi + +801025a0 : + +void ioapicenable(int irq, int cpunum) { +801025a0: 55 push %ebp + ioapic->reg = reg; +801025a1: 8b 0d 54 16 11 80 mov 0x80111654,%ecx +void ioapicenable(int irq, int cpunum) { +801025a7: 89 e5 mov %esp,%ebp +801025a9: 8b 45 08 mov 0x8(%ebp),%eax + // Mark interrupt edge-triggered, active high, + // enabled, and routed to the given cpunum, + // which happens to be that cpu's APIC ID. + ioapicwrite(REG_TABLE + 2 * irq, T_IRQ0 + irq); +801025ac: 8d 50 20 lea 0x20(%eax),%edx +801025af: 8d 44 00 10 lea 0x10(%eax,%eax,1),%eax + ioapic->reg = reg; +801025b3: 89 01 mov %eax,(%ecx) + ioapic->data = data; +801025b5: 8b 0d 54 16 11 80 mov 0x80111654,%ecx + ioapicwrite(REG_TABLE + 2 * irq + 1, cpunum << 24); +801025bb: 83 c0 01 add $0x1,%eax + ioapic->data = data; +801025be: 89 51 10 mov %edx,0x10(%ecx) + ioapicwrite(REG_TABLE + 2 * irq + 1, cpunum << 24); +801025c1: 8b 55 0c mov 0xc(%ebp),%edx + ioapic->reg = reg; +801025c4: 89 01 mov %eax,(%ecx) + ioapic->data = data; +801025c6: a1 54 16 11 80 mov 0x80111654,%eax + ioapicwrite(REG_TABLE + 2 * irq + 1, cpunum << 24); +801025cb: c1 e2 18 shl $0x18,%edx + ioapic->data = data; +801025ce: 89 50 10 mov %edx,0x10(%eax) +} +801025d1: 5d pop %ebp +801025d2: c3 ret +801025d3: 66 90 xchg %ax,%ax +801025d5: 66 90 xchg %ax,%ax +801025d7: 66 90 xchg %ax,%ax +801025d9: 66 90 xchg %ax,%ax +801025db: 66 90 xchg %ax,%ax +801025dd: 66 90 xchg %ax,%ax +801025df: 90 nop + +801025e0 : + +// Free the page of physical memory pointed at by v, +// which normally should have been returned by a +// call to kalloc(). (The exception is when +// initializing the allocator; see kinit above.) +void kfree(char *v) { +801025e0: 55 push %ebp +801025e1: 89 e5 mov %esp,%ebp +801025e3: 53 push %ebx +801025e4: 83 ec 04 sub $0x4,%esp +801025e7: 8b 5d 08 mov 0x8(%ebp),%ebx + struct run *r; + + if ((uint)v % PGSIZE || v < end || V2P(v) >= PHYSTOP) { +801025ea: f7 c3 ff 0f 00 00 test $0xfff,%ebx +801025f0: 75 76 jne 80102668 +801025f2: 81 fb f0 54 11 80 cmp $0x801154f0,%ebx +801025f8: 72 6e jb 80102668 +801025fa: 8d 83 00 00 00 80 lea -0x80000000(%ebx),%eax +80102600: 3d ff ff ff 0d cmp $0xdffffff,%eax +80102605: 77 61 ja 80102668 + panic("kfree"); + } + + // Fill with junk to catch dangling refs. + memset(v, 1, PGSIZE); +80102607: 83 ec 04 sub $0x4,%esp +8010260a: 68 00 10 00 00 push $0x1000 +8010260f: 6a 01 push $0x1 +80102611: 53 push %ebx +80102612: e8 a9 21 00 00 call 801047c0 + + if (kmem.use_lock) { +80102617: 8b 15 94 16 11 80 mov 0x80111694,%edx +8010261d: 83 c4 10 add $0x10,%esp +80102620: 85 d2 test %edx,%edx +80102622: 75 1c jne 80102640 + acquire(&kmem.lock); + } + r = (struct run*)v; + r->next = kmem.freelist; +80102624: a1 98 16 11 80 mov 0x80111698,%eax +80102629: 89 03 mov %eax,(%ebx) + kmem.freelist = r; + if (kmem.use_lock) { +8010262b: a1 94 16 11 80 mov 0x80111694,%eax + kmem.freelist = r; +80102630: 89 1d 98 16 11 80 mov %ebx,0x80111698 + if (kmem.use_lock) { +80102636: 85 c0 test %eax,%eax +80102638: 75 1e jne 80102658 + release(&kmem.lock); + } +} +8010263a: 8b 5d fc mov -0x4(%ebp),%ebx +8010263d: c9 leave +8010263e: c3 ret +8010263f: 90 nop + acquire(&kmem.lock); +80102640: 83 ec 0c sub $0xc,%esp +80102643: 68 60 16 11 80 push $0x80111660 +80102648: e8 b3 20 00 00 call 80104700 +8010264d: 83 c4 10 add $0x10,%esp +80102650: eb d2 jmp 80102624 +80102652: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + release(&kmem.lock); +80102658: c7 45 08 60 16 11 80 movl $0x80111660,0x8(%ebp) +} +8010265f: 8b 5d fc mov -0x4(%ebp),%ebx +80102662: c9 leave + release(&kmem.lock); +80102663: e9 38 20 00 00 jmp 801046a0 + panic("kfree"); +80102668: 83 ec 0c sub $0xc,%esp +8010266b: 68 46 76 10 80 push $0x80107646 +80102670: e8 1b dd ff ff call 80100390 +80102675: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010267c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80102680 : +void freerange(void *vstart, void *vend) { +80102680: 55 push %ebp +80102681: 89 e5 mov %esp,%ebp +80102683: 56 push %esi + p = (char*)PGROUNDUP((uint)vstart); +80102684: 8b 45 08 mov 0x8(%ebp),%eax +void freerange(void *vstart, void *vend) { +80102687: 8b 75 0c mov 0xc(%ebp),%esi +8010268a: 53 push %ebx + p = (char*)PGROUNDUP((uint)vstart); +8010268b: 8d 98 ff 0f 00 00 lea 0xfff(%eax),%ebx +80102691: 81 e3 00 f0 ff ff and $0xfffff000,%ebx + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +80102697: 81 c3 00 10 00 00 add $0x1000,%ebx +8010269d: 39 de cmp %ebx,%esi +8010269f: 72 23 jb 801026c4 +801026a1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + kfree(p); +801026a8: 83 ec 0c sub $0xc,%esp +801026ab: 8d 83 00 f0 ff ff lea -0x1000(%ebx),%eax + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +801026b1: 81 c3 00 10 00 00 add $0x1000,%ebx + kfree(p); +801026b7: 50 push %eax +801026b8: e8 23 ff ff ff call 801025e0 + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +801026bd: 83 c4 10 add $0x10,%esp +801026c0: 39 f3 cmp %esi,%ebx +801026c2: 76 e4 jbe 801026a8 +} +801026c4: 8d 65 f8 lea -0x8(%ebp),%esp +801026c7: 5b pop %ebx +801026c8: 5e pop %esi +801026c9: 5d pop %ebp +801026ca: c3 ret +801026cb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801026cf: 90 nop + +801026d0 : +void kinit2(void *vstart, void *vend) { +801026d0: 55 push %ebp +801026d1: 89 e5 mov %esp,%ebp +801026d3: 56 push %esi + p = (char*)PGROUNDUP((uint)vstart); +801026d4: 8b 45 08 mov 0x8(%ebp),%eax +void kinit2(void *vstart, void *vend) { +801026d7: 8b 75 0c mov 0xc(%ebp),%esi +801026da: 53 push %ebx + p = (char*)PGROUNDUP((uint)vstart); +801026db: 8d 98 ff 0f 00 00 lea 0xfff(%eax),%ebx +801026e1: 81 e3 00 f0 ff ff and $0xfffff000,%ebx + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +801026e7: 81 c3 00 10 00 00 add $0x1000,%ebx +801026ed: 39 de cmp %ebx,%esi +801026ef: 72 23 jb 80102714 +801026f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + kfree(p); +801026f8: 83 ec 0c sub $0xc,%esp +801026fb: 8d 83 00 f0 ff ff lea -0x1000(%ebx),%eax + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +80102701: 81 c3 00 10 00 00 add $0x1000,%ebx + kfree(p); +80102707: 50 push %eax +80102708: e8 d3 fe ff ff call 801025e0 + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +8010270d: 83 c4 10 add $0x10,%esp +80102710: 39 de cmp %ebx,%esi +80102712: 73 e4 jae 801026f8 + kmem.use_lock = 1; +80102714: c7 05 94 16 11 80 01 movl $0x1,0x80111694 +8010271b: 00 00 00 +} +8010271e: 8d 65 f8 lea -0x8(%ebp),%esp +80102721: 5b pop %ebx +80102722: 5e pop %esi +80102723: 5d pop %ebp +80102724: c3 ret +80102725: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010272c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80102730 : +void kinit1(void *vstart, void *vend) { +80102730: 55 push %ebp +80102731: 89 e5 mov %esp,%ebp +80102733: 56 push %esi +80102734: 53 push %ebx +80102735: 8b 75 0c mov 0xc(%ebp),%esi + initlock(&kmem.lock, "kmem"); +80102738: 83 ec 08 sub $0x8,%esp +8010273b: 68 4c 76 10 80 push $0x8010764c +80102740: 68 60 16 11 80 push $0x80111660 +80102745: e8 e6 1d 00 00 call 80104530 + p = (char*)PGROUNDUP((uint)vstart); +8010274a: 8b 45 08 mov 0x8(%ebp),%eax + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +8010274d: 83 c4 10 add $0x10,%esp + kmem.use_lock = 0; +80102750: c7 05 94 16 11 80 00 movl $0x0,0x80111694 +80102757: 00 00 00 + p = (char*)PGROUNDUP((uint)vstart); +8010275a: 8d 98 ff 0f 00 00 lea 0xfff(%eax),%ebx +80102760: 81 e3 00 f0 ff ff and $0xfffff000,%ebx + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +80102766: 81 c3 00 10 00 00 add $0x1000,%ebx +8010276c: 39 de cmp %ebx,%esi +8010276e: 72 1c jb 8010278c + kfree(p); +80102770: 83 ec 0c sub $0xc,%esp +80102773: 8d 83 00 f0 ff ff lea -0x1000(%ebx),%eax + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +80102779: 81 c3 00 10 00 00 add $0x1000,%ebx + kfree(p); +8010277f: 50 push %eax +80102780: e8 5b fe ff ff call 801025e0 + for (; p + PGSIZE <= (char*)vend; p += PGSIZE) { +80102785: 83 c4 10 add $0x10,%esp +80102788: 39 de cmp %ebx,%esi +8010278a: 73 e4 jae 80102770 +} +8010278c: 8d 65 f8 lea -0x8(%ebp),%esp +8010278f: 5b pop %ebx +80102790: 5e pop %esi +80102791: 5d pop %ebp +80102792: c3 ret +80102793: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010279a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +801027a0 : +// Returns a pointer that the kernel can use. +// Returns 0 if the memory cannot be allocated. +char* kalloc(void) { + struct run *r; + + if (kmem.use_lock) { +801027a0: a1 94 16 11 80 mov 0x80111694,%eax +801027a5: 85 c0 test %eax,%eax +801027a7: 75 1f jne 801027c8 + acquire(&kmem.lock); + } + r = kmem.freelist; +801027a9: a1 98 16 11 80 mov 0x80111698,%eax + if (r) { +801027ae: 85 c0 test %eax,%eax +801027b0: 74 0e je 801027c0 + kmem.freelist = r->next; +801027b2: 8b 10 mov (%eax),%edx +801027b4: 89 15 98 16 11 80 mov %edx,0x80111698 + } + if (kmem.use_lock) { +801027ba: c3 ret +801027bb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801027bf: 90 nop + release(&kmem.lock); + } + return (char*)r; +} +801027c0: c3 ret +801027c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +char* kalloc(void) { +801027c8: 55 push %ebp +801027c9: 89 e5 mov %esp,%ebp +801027cb: 83 ec 24 sub $0x24,%esp + acquire(&kmem.lock); +801027ce: 68 60 16 11 80 push $0x80111660 +801027d3: e8 28 1f 00 00 call 80104700 + r = kmem.freelist; +801027d8: a1 98 16 11 80 mov 0x80111698,%eax + if (kmem.use_lock) { +801027dd: 8b 15 94 16 11 80 mov 0x80111694,%edx + if (r) { +801027e3: 83 c4 10 add $0x10,%esp +801027e6: 85 c0 test %eax,%eax +801027e8: 74 08 je 801027f2 + kmem.freelist = r->next; +801027ea: 8b 08 mov (%eax),%ecx +801027ec: 89 0d 98 16 11 80 mov %ecx,0x80111698 + if (kmem.use_lock) { +801027f2: 85 d2 test %edx,%edx +801027f4: 74 16 je 8010280c + release(&kmem.lock); +801027f6: 83 ec 0c sub $0xc,%esp +801027f9: 89 45 f4 mov %eax,-0xc(%ebp) +801027fc: 68 60 16 11 80 push $0x80111660 +80102801: e8 9a 1e 00 00 call 801046a0 + return (char*)r; +80102806: 8b 45 f4 mov -0xc(%ebp),%eax + release(&kmem.lock); +80102809: 83 c4 10 add $0x10,%esp +} +8010280c: c9 leave +8010280d: c3 ret +8010280e: 66 90 xchg %ax,%ax + +80102810 : + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102810: ba 64 00 00 00 mov $0x64,%edx +80102815: ec in (%dx),%al + normalmap, shiftmap, ctlmap, ctlmap + }; + uint st, data, c; + + st = inb(KBSTATP); + if ((st & KBS_DIB) == 0) { +80102816: a8 01 test $0x1,%al +80102818: 0f 84 c2 00 00 00 je 801028e0 +int kbdgetc(void) { +8010281e: 55 push %ebp +8010281f: ba 60 00 00 00 mov $0x60,%edx +80102824: 89 e5 mov %esp,%ebp +80102826: 53 push %ebx +80102827: ec in (%dx),%al + return -1; + } + data = inb(KBDATAP); + + if (data == 0xE0) { + shift |= E0ESC; +80102828: 8b 1d 9c 16 11 80 mov 0x8011169c,%ebx + data = inb(KBDATAP); +8010282e: 0f b6 c8 movzbl %al,%ecx + if (data == 0xE0) { +80102831: 3c e0 cmp $0xe0,%al +80102833: 74 5b je 80102890 + return 0; + } + else if (data & 0x80) { + // Key released + data = (shift & E0ESC ? data : data & 0x7F); +80102835: 89 da mov %ebx,%edx +80102837: 83 e2 40 and $0x40,%edx + else if (data & 0x80) { +8010283a: 84 c0 test %al,%al +8010283c: 78 62 js 801028a0 + shift &= ~(shiftcode[data] | E0ESC); + return 0; + } + else if (shift & E0ESC) { +8010283e: 85 d2 test %edx,%edx +80102840: 74 09 je 8010284b + // Last character was an E0 escape; or with 0x80 + data |= 0x80; +80102842: 83 c8 80 or $0xffffff80,%eax + shift &= ~E0ESC; +80102845: 83 e3 bf and $0xffffffbf,%ebx + data |= 0x80; +80102848: 0f b6 c8 movzbl %al,%ecx + } + + shift |= shiftcode[data]; +8010284b: 0f b6 91 80 77 10 80 movzbl -0x7fef8880(%ecx),%edx + shift ^= togglecode[data]; +80102852: 0f b6 81 80 76 10 80 movzbl -0x7fef8980(%ecx),%eax + shift |= shiftcode[data]; +80102859: 09 da or %ebx,%edx + shift ^= togglecode[data]; +8010285b: 31 c2 xor %eax,%edx + c = charcode[shift & (CTL | SHIFT)][data]; +8010285d: 89 d0 mov %edx,%eax + shift ^= togglecode[data]; +8010285f: 89 15 9c 16 11 80 mov %edx,0x8011169c + c = charcode[shift & (CTL | SHIFT)][data]; +80102865: 83 e0 03 and $0x3,%eax + if (shift & CAPSLOCK) { +80102868: 83 e2 08 and $0x8,%edx + c = charcode[shift & (CTL | SHIFT)][data]; +8010286b: 8b 04 85 60 76 10 80 mov -0x7fef89a0(,%eax,4),%eax +80102872: 0f b6 04 08 movzbl (%eax,%ecx,1),%eax + if (shift & CAPSLOCK) { +80102876: 74 0b je 80102883 + if ('a' <= c && c <= 'z') { +80102878: 8d 50 9f lea -0x61(%eax),%edx +8010287b: 83 fa 19 cmp $0x19,%edx +8010287e: 77 48 ja 801028c8 + c += 'A' - 'a'; +80102880: 83 e8 20 sub $0x20,%eax + else if ('A' <= c && c <= 'Z') { + c += 'a' - 'A'; + } + } + return c; +} +80102883: 8b 5d fc mov -0x4(%ebp),%ebx +80102886: c9 leave +80102887: c3 ret +80102888: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010288f: 90 nop + shift |= E0ESC; +80102890: 83 cb 40 or $0x40,%ebx + return 0; +80102893: 31 c0 xor %eax,%eax + shift |= E0ESC; +80102895: 89 1d 9c 16 11 80 mov %ebx,0x8011169c +} +8010289b: 8b 5d fc mov -0x4(%ebp),%ebx +8010289e: c9 leave +8010289f: c3 ret + data = (shift & E0ESC ? data : data & 0x7F); +801028a0: 83 e0 7f and $0x7f,%eax +801028a3: 85 d2 test %edx,%edx +801028a5: 0f 44 c8 cmove %eax,%ecx + shift &= ~(shiftcode[data] | E0ESC); +801028a8: 0f b6 81 80 77 10 80 movzbl -0x7fef8880(%ecx),%eax +801028af: 83 c8 40 or $0x40,%eax +801028b2: 0f b6 c0 movzbl %al,%eax +801028b5: f7 d0 not %eax +801028b7: 21 d8 and %ebx,%eax +} +801028b9: 8b 5d fc mov -0x4(%ebp),%ebx + shift &= ~(shiftcode[data] | E0ESC); +801028bc: a3 9c 16 11 80 mov %eax,0x8011169c + return 0; +801028c1: 31 c0 xor %eax,%eax +} +801028c3: c9 leave +801028c4: c3 ret +801028c5: 8d 76 00 lea 0x0(%esi),%esi + else if ('A' <= c && c <= 'Z') { +801028c8: 8d 48 bf lea -0x41(%eax),%ecx + c += 'a' - 'A'; +801028cb: 8d 50 20 lea 0x20(%eax),%edx +} +801028ce: 8b 5d fc mov -0x4(%ebp),%ebx +801028d1: c9 leave + c += 'a' - 'A'; +801028d2: 83 f9 1a cmp $0x1a,%ecx +801028d5: 0f 42 c2 cmovb %edx,%eax +} +801028d8: c3 ret +801028d9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return -1; +801028e0: b8 ff ff ff ff mov $0xffffffff,%eax +} +801028e5: c3 ret +801028e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801028ed: 8d 76 00 lea 0x0(%esi),%esi + +801028f0 : + +void kbdintr(void) { +801028f0: 55 push %ebp +801028f1: 89 e5 mov %esp,%ebp +801028f3: 83 ec 14 sub $0x14,%esp + consoleintr(kbdgetc); +801028f6: 68 10 28 10 80 push $0x80102810 +801028fb: e8 e0 df ff ff call 801008e0 +} +80102900: 83 c4 10 add $0x10,%esp +80102903: c9 leave +80102904: c3 ret +80102905: 66 90 xchg %ax,%ax +80102907: 66 90 xchg %ax,%ax +80102909: 66 90 xchg %ax,%ax +8010290b: 66 90 xchg %ax,%ax +8010290d: 66 90 xchg %ax,%ax +8010290f: 90 nop + +80102910 : + lapic[index] = value; + lapic[ID]; // wait for write to finish, by reading +} + +void lapicinit(void) { + if (!lapic) { +80102910: a1 a0 16 11 80 mov 0x801116a0,%eax +80102915: 85 c0 test %eax,%eax +80102917: 0f 84 cb 00 00 00 je 801029e8 + lapic[index] = value; +8010291d: c7 80 f0 00 00 00 3f movl $0x13f,0xf0(%eax) +80102924: 01 00 00 + lapic[ID]; // wait for write to finish, by reading +80102927: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +8010292a: c7 80 e0 03 00 00 0b movl $0xb,0x3e0(%eax) +80102931: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +80102934: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +80102937: c7 80 20 03 00 00 20 movl $0x20020,0x320(%eax) +8010293e: 00 02 00 + lapic[ID]; // wait for write to finish, by reading +80102941: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +80102944: c7 80 80 03 00 00 80 movl $0x989680,0x380(%eax) +8010294b: 96 98 00 + lapic[ID]; // wait for write to finish, by reading +8010294e: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +80102951: c7 80 50 03 00 00 00 movl $0x10000,0x350(%eax) +80102958: 00 01 00 + lapic[ID]; // wait for write to finish, by reading +8010295b: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +8010295e: c7 80 60 03 00 00 00 movl $0x10000,0x360(%eax) +80102965: 00 01 00 + lapic[ID]; // wait for write to finish, by reading +80102968: 8b 50 20 mov 0x20(%eax),%edx + lapicw(LINT0, MASKED); + lapicw(LINT1, MASKED); + + // Disable performance counter overflow interrupts + // on machines that provide that interrupt entry. + if (((lapic[VER] >> 16) & 0xFF) >= 4) { +8010296b: 8b 50 30 mov 0x30(%eax),%edx +8010296e: c1 ea 10 shr $0x10,%edx +80102971: 81 e2 fc 00 00 00 and $0xfc,%edx +80102977: 75 77 jne 801029f0 + lapic[index] = value; +80102979: c7 80 70 03 00 00 33 movl $0x33,0x370(%eax) +80102980: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +80102983: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +80102986: c7 80 80 02 00 00 00 movl $0x0,0x280(%eax) +8010298d: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +80102990: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +80102993: c7 80 80 02 00 00 00 movl $0x0,0x280(%eax) +8010299a: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +8010299d: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +801029a0: c7 80 b0 00 00 00 00 movl $0x0,0xb0(%eax) +801029a7: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +801029aa: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +801029ad: c7 80 10 03 00 00 00 movl $0x0,0x310(%eax) +801029b4: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +801029b7: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +801029ba: c7 80 00 03 00 00 00 movl $0x88500,0x300(%eax) +801029c1: 85 08 00 + lapic[ID]; // wait for write to finish, by reading +801029c4: 8b 50 20 mov 0x20(%eax),%edx +801029c7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801029ce: 66 90 xchg %ax,%ax + lapicw(EOI, 0); + + // Send an Init Level De-Assert to synchronise arbitration ID's. + lapicw(ICRHI, 0); + lapicw(ICRLO, BCAST | INIT | LEVEL); + while (lapic[ICRLO] & DELIVS) { +801029d0: 8b 90 00 03 00 00 mov 0x300(%eax),%edx +801029d6: 80 e6 10 and $0x10,%dh +801029d9: 75 f5 jne 801029d0 + lapic[index] = value; +801029db: c7 80 80 00 00 00 00 movl $0x0,0x80(%eax) +801029e2: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +801029e5: 8b 40 20 mov 0x20(%eax),%eax + ; + } + + // Enable interrupts on the APIC (but not on the processor). + lapicw(TPR, 0); +} +801029e8: c3 ret +801029e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + lapic[index] = value; +801029f0: c7 80 40 03 00 00 00 movl $0x10000,0x340(%eax) +801029f7: 00 01 00 + lapic[ID]; // wait for write to finish, by reading +801029fa: 8b 50 20 mov 0x20(%eax),%edx +} +801029fd: e9 77 ff ff ff jmp 80102979 +80102a02: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102a09: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80102a10 : + +int lapicid(void) { + if (!lapic) { +80102a10: a1 a0 16 11 80 mov 0x801116a0,%eax +80102a15: 85 c0 test %eax,%eax +80102a17: 74 07 je 80102a20 + return 0; + } + return lapic[ID] >> 24; +80102a19: 8b 40 20 mov 0x20(%eax),%eax +80102a1c: c1 e8 18 shr $0x18,%eax +80102a1f: c3 ret + return 0; +80102a20: 31 c0 xor %eax,%eax +} +80102a22: c3 ret +80102a23: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102a2a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80102a30 : + +// Acknowledge interrupt. +void lapiceoi(void) { + if (lapic) { +80102a30: a1 a0 16 11 80 mov 0x801116a0,%eax +80102a35: 85 c0 test %eax,%eax +80102a37: 74 0d je 80102a46 + lapic[index] = value; +80102a39: c7 80 b0 00 00 00 00 movl $0x0,0xb0(%eax) +80102a40: 00 00 00 + lapic[ID]; // wait for write to finish, by reading +80102a43: 8b 40 20 mov 0x20(%eax),%eax + lapicw(EOI, 0); + } +} +80102a46: c3 ret +80102a47: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102a4e: 66 90 xchg %ax,%ax + +80102a50 : + +// Spin for a given number of microseconds. +// On real hardware would want to tune this dynamically. +void microdelay(int us) { +} +80102a50: c3 ret +80102a51: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102a58: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102a5f: 90 nop + +80102a60 : +#define CMOS_PORT 0x70 +#define CMOS_RETURN 0x71 + +// Start additional processor running entry code at addr. +// See Appendix B of MultiProcessor Specification. +void lapicstartap(uchar apicid, uint addr) { +80102a60: 55 push %ebp + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102a61: b8 0f 00 00 00 mov $0xf,%eax +80102a66: ba 70 00 00 00 mov $0x70,%edx +80102a6b: 89 e5 mov %esp,%ebp +80102a6d: 53 push %ebx +80102a6e: 8b 4d 0c mov 0xc(%ebp),%ecx +80102a71: 8b 5d 08 mov 0x8(%ebp),%ebx +80102a74: ee out %al,(%dx) +80102a75: b8 0a 00 00 00 mov $0xa,%eax +80102a7a: ba 71 00 00 00 mov $0x71,%edx +80102a7f: ee out %al,(%dx) + // and the warm reset vector (DWORD based at 40:67) to point at + // the AP startup code prior to the [universal startup algorithm]." + outb(CMOS_PORT, 0xF); // offset 0xF is shutdown code + outb(CMOS_PORT + 1, 0x0A); + wrv = (ushort*)P2V((0x40 << 4 | 0x67)); // Warm reset vector + wrv[0] = 0; +80102a80: 31 c0 xor %eax,%eax + wrv[1] = addr >> 4; + + // "Universal startup algorithm." + // Send INIT (level-triggered) interrupt to reset other CPU. + lapicw(ICRHI, apicid << 24); +80102a82: c1 e3 18 shl $0x18,%ebx + wrv[0] = 0; +80102a85: 66 a3 67 04 00 80 mov %ax,0x80000467 + wrv[1] = addr >> 4; +80102a8b: 89 c8 mov %ecx,%eax + // when it is in the halted state due to an INIT. So the second + // should be ignored, but it is part of the official Intel algorithm. + // Bochs complains about the second one. Too bad for Bochs. + for (i = 0; i < 2; i++) { + lapicw(ICRHI, apicid << 24); + lapicw(ICRLO, STARTUP | (addr >> 12)); +80102a8d: c1 e9 0c shr $0xc,%ecx + lapicw(ICRHI, apicid << 24); +80102a90: 89 da mov %ebx,%edx + wrv[1] = addr >> 4; +80102a92: c1 e8 04 shr $0x4,%eax + lapicw(ICRLO, STARTUP | (addr >> 12)); +80102a95: 80 cd 06 or $0x6,%ch + wrv[1] = addr >> 4; +80102a98: 66 a3 69 04 00 80 mov %ax,0x80000469 + lapic[index] = value; +80102a9e: a1 a0 16 11 80 mov 0x801116a0,%eax +80102aa3: 89 98 10 03 00 00 mov %ebx,0x310(%eax) + lapic[ID]; // wait for write to finish, by reading +80102aa9: 8b 58 20 mov 0x20(%eax),%ebx + lapic[index] = value; +80102aac: c7 80 00 03 00 00 00 movl $0xc500,0x300(%eax) +80102ab3: c5 00 00 + lapic[ID]; // wait for write to finish, by reading +80102ab6: 8b 58 20 mov 0x20(%eax),%ebx + lapic[index] = value; +80102ab9: c7 80 00 03 00 00 00 movl $0x8500,0x300(%eax) +80102ac0: 85 00 00 + lapic[ID]; // wait for write to finish, by reading +80102ac3: 8b 58 20 mov 0x20(%eax),%ebx + lapic[index] = value; +80102ac6: 89 90 10 03 00 00 mov %edx,0x310(%eax) + lapic[ID]; // wait for write to finish, by reading +80102acc: 8b 58 20 mov 0x20(%eax),%ebx + lapic[index] = value; +80102acf: 89 88 00 03 00 00 mov %ecx,0x300(%eax) + lapic[ID]; // wait for write to finish, by reading +80102ad5: 8b 58 20 mov 0x20(%eax),%ebx + lapic[index] = value; +80102ad8: 89 90 10 03 00 00 mov %edx,0x310(%eax) + lapic[ID]; // wait for write to finish, by reading +80102ade: 8b 50 20 mov 0x20(%eax),%edx + lapic[index] = value; +80102ae1: 89 88 00 03 00 00 mov %ecx,0x300(%eax) + lapic[ID]; // wait for write to finish, by reading +80102ae7: 8b 40 20 mov 0x20(%eax),%eax + microdelay(200); + } +} +80102aea: 8b 5d fc mov -0x4(%ebp),%ebx +80102aed: c9 leave +80102aee: c3 ret +80102aef: 90 nop + +80102af0 : + r->month = cmos_read(MONTH); + r->year = cmos_read(YEAR); +} + +// qemu seems to use 24-hour GWT and the values are BCD encoded +void cmostime(struct rtcdate *r) { +80102af0: 55 push %ebp +80102af1: b8 0b 00 00 00 mov $0xb,%eax +80102af6: ba 70 00 00 00 mov $0x70,%edx +80102afb: 89 e5 mov %esp,%ebp +80102afd: 57 push %edi +80102afe: 56 push %esi +80102aff: 53 push %ebx +80102b00: 83 ec 4c sub $0x4c,%esp +80102b03: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b04: ba 71 00 00 00 mov $0x71,%edx +80102b09: ec in (%dx),%al + struct rtcdate t1, t2; + int sb, bcd; + + sb = cmos_read(CMOS_STATB); + + bcd = (sb & (1 << 2)) == 0; +80102b0a: 83 e0 04 and $0x4,%eax + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b0d: bb 70 00 00 00 mov $0x70,%ebx +80102b12: 88 45 b3 mov %al,-0x4d(%ebp) +80102b15: 8d 76 00 lea 0x0(%esi),%esi +80102b18: 31 c0 xor %eax,%eax +80102b1a: 89 da mov %ebx,%edx +80102b1c: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b1d: b9 71 00 00 00 mov $0x71,%ecx +80102b22: 89 ca mov %ecx,%edx +80102b24: ec in (%dx),%al +80102b25: 88 45 b7 mov %al,-0x49(%ebp) + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b28: 89 da mov %ebx,%edx +80102b2a: b8 02 00 00 00 mov $0x2,%eax +80102b2f: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b30: 89 ca mov %ecx,%edx +80102b32: ec in (%dx),%al +80102b33: 88 45 b6 mov %al,-0x4a(%ebp) + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b36: 89 da mov %ebx,%edx +80102b38: b8 04 00 00 00 mov $0x4,%eax +80102b3d: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b3e: 89 ca mov %ecx,%edx +80102b40: ec in (%dx),%al +80102b41: 88 45 b5 mov %al,-0x4b(%ebp) + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b44: 89 da mov %ebx,%edx +80102b46: b8 07 00 00 00 mov $0x7,%eax +80102b4b: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b4c: 89 ca mov %ecx,%edx +80102b4e: ec in (%dx),%al +80102b4f: 88 45 b4 mov %al,-0x4c(%ebp) + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b52: 89 da mov %ebx,%edx +80102b54: b8 08 00 00 00 mov $0x8,%eax +80102b59: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b5a: 89 ca mov %ecx,%edx +80102b5c: ec in (%dx),%al +80102b5d: 89 c7 mov %eax,%edi + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b5f: 89 da mov %ebx,%edx +80102b61: b8 09 00 00 00 mov $0x9,%eax +80102b66: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b67: 89 ca mov %ecx,%edx +80102b69: ec in (%dx),%al +80102b6a: 89 c6 mov %eax,%esi + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b6c: 89 da mov %ebx,%edx +80102b6e: b8 0a 00 00 00 mov $0xa,%eax +80102b73: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102b74: 89 ca mov %ecx,%edx +80102b76: ec in (%dx),%al + + // make sure CMOS doesn't modify time while we read it + for (;;) { + fill_rtcdate(&t1); + if (cmos_read(CMOS_STATA) & CMOS_UIP) { +80102b77: 84 c0 test %al,%al +80102b79: 78 9d js 80102b18 + return inb(CMOS_RETURN); +80102b7b: 0f b6 45 b7 movzbl -0x49(%ebp),%eax +80102b7f: 89 fa mov %edi,%edx +80102b81: 0f b6 fa movzbl %dl,%edi +80102b84: 89 f2 mov %esi,%edx +80102b86: 89 45 b8 mov %eax,-0x48(%ebp) +80102b89: 0f b6 45 b6 movzbl -0x4a(%ebp),%eax +80102b8d: 0f b6 f2 movzbl %dl,%esi + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102b90: 89 da mov %ebx,%edx +80102b92: 89 7d c8 mov %edi,-0x38(%ebp) +80102b95: 89 45 bc mov %eax,-0x44(%ebp) +80102b98: 0f b6 45 b5 movzbl -0x4b(%ebp),%eax +80102b9c: 89 75 cc mov %esi,-0x34(%ebp) +80102b9f: 89 45 c0 mov %eax,-0x40(%ebp) +80102ba2: 0f b6 45 b4 movzbl -0x4c(%ebp),%eax +80102ba6: 89 45 c4 mov %eax,-0x3c(%ebp) +80102ba9: 31 c0 xor %eax,%eax +80102bab: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102bac: 89 ca mov %ecx,%edx +80102bae: ec in (%dx),%al +80102baf: 0f b6 c0 movzbl %al,%eax + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102bb2: 89 da mov %ebx,%edx +80102bb4: 89 45 d0 mov %eax,-0x30(%ebp) +80102bb7: b8 02 00 00 00 mov $0x2,%eax +80102bbc: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102bbd: 89 ca mov %ecx,%edx +80102bbf: ec in (%dx),%al +80102bc0: 0f b6 c0 movzbl %al,%eax + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102bc3: 89 da mov %ebx,%edx +80102bc5: 89 45 d4 mov %eax,-0x2c(%ebp) +80102bc8: b8 04 00 00 00 mov $0x4,%eax +80102bcd: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102bce: 89 ca mov %ecx,%edx +80102bd0: ec in (%dx),%al +80102bd1: 0f b6 c0 movzbl %al,%eax + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102bd4: 89 da mov %ebx,%edx +80102bd6: 89 45 d8 mov %eax,-0x28(%ebp) +80102bd9: b8 07 00 00 00 mov $0x7,%eax +80102bde: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102bdf: 89 ca mov %ecx,%edx +80102be1: ec in (%dx),%al +80102be2: 0f b6 c0 movzbl %al,%eax + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102be5: 89 da mov %ebx,%edx +80102be7: 89 45 dc mov %eax,-0x24(%ebp) +80102bea: b8 08 00 00 00 mov $0x8,%eax +80102bef: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102bf0: 89 ca mov %ecx,%edx +80102bf2: ec in (%dx),%al +80102bf3: 0f b6 c0 movzbl %al,%eax + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80102bf6: 89 da mov %ebx,%edx +80102bf8: 89 45 e0 mov %eax,-0x20(%ebp) +80102bfb: b8 09 00 00 00 mov $0x9,%eax +80102c00: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80102c01: 89 ca mov %ecx,%edx +80102c03: ec in (%dx),%al +80102c04: 0f b6 c0 movzbl %al,%eax + continue; + } + fill_rtcdate(&t2); + if (memcmp(&t1, &t2, sizeof(t1)) == 0) { +80102c07: 83 ec 04 sub $0x4,%esp + return inb(CMOS_RETURN); +80102c0a: 89 45 e4 mov %eax,-0x1c(%ebp) + if (memcmp(&t1, &t2, sizeof(t1)) == 0) { +80102c0d: 8d 45 d0 lea -0x30(%ebp),%eax +80102c10: 6a 18 push $0x18 +80102c12: 50 push %eax +80102c13: 8d 45 b8 lea -0x48(%ebp),%eax +80102c16: 50 push %eax +80102c17: e8 f4 1b 00 00 call 80104810 +80102c1c: 83 c4 10 add $0x10,%esp +80102c1f: 85 c0 test %eax,%eax +80102c21: 0f 85 f1 fe ff ff jne 80102b18 + break; + } + } + + // convert + if (bcd) { +80102c27: 80 7d b3 00 cmpb $0x0,-0x4d(%ebp) +80102c2b: 75 78 jne 80102ca5 +#define CONV(x) (t1.x = ((t1.x >> 4) * 10) + (t1.x & 0xf)) + CONV(second); +80102c2d: 8b 45 b8 mov -0x48(%ebp),%eax +80102c30: 89 c2 mov %eax,%edx +80102c32: 83 e0 0f and $0xf,%eax +80102c35: c1 ea 04 shr $0x4,%edx +80102c38: 8d 14 92 lea (%edx,%edx,4),%edx +80102c3b: 8d 04 50 lea (%eax,%edx,2),%eax +80102c3e: 89 45 b8 mov %eax,-0x48(%ebp) + CONV(minute); +80102c41: 8b 45 bc mov -0x44(%ebp),%eax +80102c44: 89 c2 mov %eax,%edx +80102c46: 83 e0 0f and $0xf,%eax +80102c49: c1 ea 04 shr $0x4,%edx +80102c4c: 8d 14 92 lea (%edx,%edx,4),%edx +80102c4f: 8d 04 50 lea (%eax,%edx,2),%eax +80102c52: 89 45 bc mov %eax,-0x44(%ebp) + CONV(hour ); +80102c55: 8b 45 c0 mov -0x40(%ebp),%eax +80102c58: 89 c2 mov %eax,%edx +80102c5a: 83 e0 0f and $0xf,%eax +80102c5d: c1 ea 04 shr $0x4,%edx +80102c60: 8d 14 92 lea (%edx,%edx,4),%edx +80102c63: 8d 04 50 lea (%eax,%edx,2),%eax +80102c66: 89 45 c0 mov %eax,-0x40(%ebp) + CONV(day ); +80102c69: 8b 45 c4 mov -0x3c(%ebp),%eax +80102c6c: 89 c2 mov %eax,%edx +80102c6e: 83 e0 0f and $0xf,%eax +80102c71: c1 ea 04 shr $0x4,%edx +80102c74: 8d 14 92 lea (%edx,%edx,4),%edx +80102c77: 8d 04 50 lea (%eax,%edx,2),%eax +80102c7a: 89 45 c4 mov %eax,-0x3c(%ebp) + CONV(month ); +80102c7d: 8b 45 c8 mov -0x38(%ebp),%eax +80102c80: 89 c2 mov %eax,%edx +80102c82: 83 e0 0f and $0xf,%eax +80102c85: c1 ea 04 shr $0x4,%edx +80102c88: 8d 14 92 lea (%edx,%edx,4),%edx +80102c8b: 8d 04 50 lea (%eax,%edx,2),%eax +80102c8e: 89 45 c8 mov %eax,-0x38(%ebp) + CONV(year ); +80102c91: 8b 45 cc mov -0x34(%ebp),%eax +80102c94: 89 c2 mov %eax,%edx +80102c96: 83 e0 0f and $0xf,%eax +80102c99: c1 ea 04 shr $0x4,%edx +80102c9c: 8d 14 92 lea (%edx,%edx,4),%edx +80102c9f: 8d 04 50 lea (%eax,%edx,2),%eax +80102ca2: 89 45 cc mov %eax,-0x34(%ebp) +#undef CONV + } + + *r = t1; +80102ca5: 8b 75 08 mov 0x8(%ebp),%esi +80102ca8: 8b 45 b8 mov -0x48(%ebp),%eax +80102cab: 89 06 mov %eax,(%esi) +80102cad: 8b 45 bc mov -0x44(%ebp),%eax +80102cb0: 89 46 04 mov %eax,0x4(%esi) +80102cb3: 8b 45 c0 mov -0x40(%ebp),%eax +80102cb6: 89 46 08 mov %eax,0x8(%esi) +80102cb9: 8b 45 c4 mov -0x3c(%ebp),%eax +80102cbc: 89 46 0c mov %eax,0xc(%esi) +80102cbf: 8b 45 c8 mov -0x38(%ebp),%eax +80102cc2: 89 46 10 mov %eax,0x10(%esi) +80102cc5: 8b 45 cc mov -0x34(%ebp),%eax +80102cc8: 89 46 14 mov %eax,0x14(%esi) + r->year += 2000; +80102ccb: 81 46 14 d0 07 00 00 addl $0x7d0,0x14(%esi) +} +80102cd2: 8d 65 f4 lea -0xc(%ebp),%esp +80102cd5: 5b pop %ebx +80102cd6: 5e pop %esi +80102cd7: 5f pop %edi +80102cd8: 5d pop %ebp +80102cd9: c3 ret +80102cda: 66 90 xchg %ax,%ax +80102cdc: 66 90 xchg %ax,%ax +80102cde: 66 90 xchg %ax,%ax + +80102ce0 : +static void +install_trans(void) +{ + int tail; + + for (tail = 0; tail < log.lh.n; tail++) { +80102ce0: 8b 0d 08 17 11 80 mov 0x80111708,%ecx +80102ce6: 85 c9 test %ecx,%ecx +80102ce8: 0f 8e 8a 00 00 00 jle 80102d78 +{ +80102cee: 55 push %ebp +80102cef: 89 e5 mov %esp,%ebp +80102cf1: 57 push %edi + for (tail = 0; tail < log.lh.n; tail++) { +80102cf2: 31 ff xor %edi,%edi +{ +80102cf4: 56 push %esi +80102cf5: 53 push %ebx +80102cf6: 83 ec 0c sub $0xc,%esp +80102cf9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block +80102d00: a1 f4 16 11 80 mov 0x801116f4,%eax +80102d05: 83 ec 08 sub $0x8,%esp +80102d08: 01 f8 add %edi,%eax +80102d0a: 83 c0 01 add $0x1,%eax +80102d0d: 50 push %eax +80102d0e: ff 35 04 17 11 80 push 0x80111704 +80102d14: e8 b7 d3 ff ff call 801000d0 +80102d19: 89 c6 mov %eax,%esi + struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst +80102d1b: 58 pop %eax +80102d1c: 5a pop %edx +80102d1d: ff 34 bd 0c 17 11 80 push -0x7feee8f4(,%edi,4) +80102d24: ff 35 04 17 11 80 push 0x80111704 + for (tail = 0; tail < log.lh.n; tail++) { +80102d2a: 83 c7 01 add $0x1,%edi + struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst +80102d2d: e8 9e d3 ff ff call 801000d0 + memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst +80102d32: 83 c4 0c add $0xc,%esp + struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst +80102d35: 89 c3 mov %eax,%ebx + memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst +80102d37: 8d 46 5c lea 0x5c(%esi),%eax +80102d3a: 68 00 02 00 00 push $0x200 +80102d3f: 50 push %eax +80102d40: 8d 43 5c lea 0x5c(%ebx),%eax +80102d43: 50 push %eax +80102d44: e8 17 1b 00 00 call 80104860 + bwrite(dbuf); // write dst to disk +80102d49: 89 1c 24 mov %ebx,(%esp) +80102d4c: e8 5f d4 ff ff call 801001b0 + brelse(lbuf); +80102d51: 89 34 24 mov %esi,(%esp) +80102d54: e8 97 d4 ff ff call 801001f0 + brelse(dbuf); +80102d59: 89 1c 24 mov %ebx,(%esp) +80102d5c: e8 8f d4 ff ff call 801001f0 + for (tail = 0; tail < log.lh.n; tail++) { +80102d61: 83 c4 10 add $0x10,%esp +80102d64: 39 3d 08 17 11 80 cmp %edi,0x80111708 +80102d6a: 7f 94 jg 80102d00 + } +} +80102d6c: 8d 65 f4 lea -0xc(%ebp),%esp +80102d6f: 5b pop %ebx +80102d70: 5e pop %esi +80102d71: 5f pop %edi +80102d72: 5d pop %ebp +80102d73: c3 ret +80102d74: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80102d78: c3 ret +80102d79: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80102d80 : +// Write in-memory log header to disk. +// This is the true point at which the +// current transaction commits. +static void +write_head(void) +{ +80102d80: 55 push %ebp +80102d81: 89 e5 mov %esp,%ebp +80102d83: 53 push %ebx +80102d84: 83 ec 0c sub $0xc,%esp + struct buf *buf = bread(log.dev, log.start); +80102d87: ff 35 f4 16 11 80 push 0x801116f4 +80102d8d: ff 35 04 17 11 80 push 0x80111704 +80102d93: e8 38 d3 ff ff call 801000d0 + struct logheader *hb = (struct logheader *) (buf->data); + int i; + hb->n = log.lh.n; + for (i = 0; i < log.lh.n; i++) { +80102d98: 83 c4 10 add $0x10,%esp + struct buf *buf = bread(log.dev, log.start); +80102d9b: 89 c3 mov %eax,%ebx + hb->n = log.lh.n; +80102d9d: a1 08 17 11 80 mov 0x80111708,%eax +80102da2: 89 43 5c mov %eax,0x5c(%ebx) + for (i = 0; i < log.lh.n; i++) { +80102da5: 85 c0 test %eax,%eax +80102da7: 7e 19 jle 80102dc2 +80102da9: 31 d2 xor %edx,%edx +80102dab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80102daf: 90 nop + hb->block[i] = log.lh.block[i]; +80102db0: 8b 0c 95 0c 17 11 80 mov -0x7feee8f4(,%edx,4),%ecx +80102db7: 89 4c 93 60 mov %ecx,0x60(%ebx,%edx,4) + for (i = 0; i < log.lh.n; i++) { +80102dbb: 83 c2 01 add $0x1,%edx +80102dbe: 39 d0 cmp %edx,%eax +80102dc0: 75 ee jne 80102db0 + } + bwrite(buf); +80102dc2: 83 ec 0c sub $0xc,%esp +80102dc5: 53 push %ebx +80102dc6: e8 e5 d3 ff ff call 801001b0 + brelse(buf); +80102dcb: 89 1c 24 mov %ebx,(%esp) +80102dce: e8 1d d4 ff ff call 801001f0 +} +80102dd3: 8b 5d fc mov -0x4(%ebp),%ebx +80102dd6: 83 c4 10 add $0x10,%esp +80102dd9: c9 leave +80102dda: c3 ret +80102ddb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80102ddf: 90 nop + +80102de0 : +{ +80102de0: 55 push %ebp +80102de1: 89 e5 mov %esp,%ebp +80102de3: 53 push %ebx +80102de4: 83 ec 2c sub $0x2c,%esp +80102de7: 8b 5d 08 mov 0x8(%ebp),%ebx + initlock(&log.lock, "log"); +80102dea: 68 80 78 10 80 push $0x80107880 +80102def: 68 c0 16 11 80 push $0x801116c0 +80102df4: e8 37 17 00 00 call 80104530 + readsb(dev, &sb); +80102df9: 58 pop %eax +80102dfa: 8d 45 dc lea -0x24(%ebp),%eax +80102dfd: 5a pop %edx +80102dfe: 50 push %eax +80102dff: 53 push %ebx +80102e00: e8 3b e8 ff ff call 80101640 + log.start = sb.logstart; +80102e05: 8b 45 ec mov -0x14(%ebp),%eax + struct buf *buf = bread(log.dev, log.start); +80102e08: 59 pop %ecx + log.dev = dev; +80102e09: 89 1d 04 17 11 80 mov %ebx,0x80111704 + log.size = sb.nlog; +80102e0f: 8b 55 e8 mov -0x18(%ebp),%edx + log.start = sb.logstart; +80102e12: a3 f4 16 11 80 mov %eax,0x801116f4 + log.size = sb.nlog; +80102e17: 89 15 f8 16 11 80 mov %edx,0x801116f8 + struct buf *buf = bread(log.dev, log.start); +80102e1d: 5a pop %edx +80102e1e: 50 push %eax +80102e1f: 53 push %ebx +80102e20: e8 ab d2 ff ff call 801000d0 + for (i = 0; i < log.lh.n; i++) { +80102e25: 83 c4 10 add $0x10,%esp + log.lh.n = lh->n; +80102e28: 8b 58 5c mov 0x5c(%eax),%ebx +80102e2b: 89 1d 08 17 11 80 mov %ebx,0x80111708 + for (i = 0; i < log.lh.n; i++) { +80102e31: 85 db test %ebx,%ebx +80102e33: 7e 1d jle 80102e52 +80102e35: 31 d2 xor %edx,%edx +80102e37: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102e3e: 66 90 xchg %ax,%ax + log.lh.block[i] = lh->block[i]; +80102e40: 8b 4c 90 60 mov 0x60(%eax,%edx,4),%ecx +80102e44: 89 0c 95 0c 17 11 80 mov %ecx,-0x7feee8f4(,%edx,4) + for (i = 0; i < log.lh.n; i++) { +80102e4b: 83 c2 01 add $0x1,%edx +80102e4e: 39 d3 cmp %edx,%ebx +80102e50: 75 ee jne 80102e40 + brelse(buf); +80102e52: 83 ec 0c sub $0xc,%esp +80102e55: 50 push %eax +80102e56: e8 95 d3 ff ff call 801001f0 + +static void +recover_from_log(void) +{ + read_head(); + install_trans(); // if committed, copy from log to disk +80102e5b: e8 80 fe ff ff call 80102ce0 + log.lh.n = 0; +80102e60: c7 05 08 17 11 80 00 movl $0x0,0x80111708 +80102e67: 00 00 00 + write_head(); // clear the log +80102e6a: e8 11 ff ff ff call 80102d80 +} +80102e6f: 8b 5d fc mov -0x4(%ebp),%ebx +80102e72: 83 c4 10 add $0x10,%esp +80102e75: c9 leave +80102e76: c3 ret +80102e77: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102e7e: 66 90 xchg %ax,%ax + +80102e80 : +} + +// called at the start of each FS system call. +void +begin_op(void) +{ +80102e80: 55 push %ebp +80102e81: 89 e5 mov %esp,%ebp +80102e83: 83 ec 14 sub $0x14,%esp + acquire(&log.lock); +80102e86: 68 c0 16 11 80 push $0x801116c0 +80102e8b: e8 70 18 00 00 call 80104700 +80102e90: 83 c4 10 add $0x10,%esp +80102e93: eb 18 jmp 80102ead +80102e95: 8d 76 00 lea 0x0(%esi),%esi + while(1){ + if(log.committing){ + sleep(&log, &log.lock); +80102e98: 83 ec 08 sub $0x8,%esp +80102e9b: 68 c0 16 11 80 push $0x801116c0 +80102ea0: 68 c0 16 11 80 push $0x801116c0 +80102ea5: e8 f6 12 00 00 call 801041a0 +80102eaa: 83 c4 10 add $0x10,%esp + if(log.committing){ +80102ead: a1 00 17 11 80 mov 0x80111700,%eax +80102eb2: 85 c0 test %eax,%eax +80102eb4: 75 e2 jne 80102e98 + } else if(log.lh.n + (log.outstanding+1)*MAXOPBLOCKS > LOGSIZE){ +80102eb6: a1 fc 16 11 80 mov 0x801116fc,%eax +80102ebb: 8b 15 08 17 11 80 mov 0x80111708,%edx +80102ec1: 83 c0 01 add $0x1,%eax +80102ec4: 8d 0c 80 lea (%eax,%eax,4),%ecx +80102ec7: 8d 14 4a lea (%edx,%ecx,2),%edx +80102eca: 83 fa 1e cmp $0x1e,%edx +80102ecd: 7f c9 jg 80102e98 + // this op might exhaust log space; wait for commit. + sleep(&log, &log.lock); + } else { + log.outstanding += 1; + release(&log.lock); +80102ecf: 83 ec 0c sub $0xc,%esp + log.outstanding += 1; +80102ed2: a3 fc 16 11 80 mov %eax,0x801116fc + release(&log.lock); +80102ed7: 68 c0 16 11 80 push $0x801116c0 +80102edc: e8 bf 17 00 00 call 801046a0 + break; + } + } +} +80102ee1: 83 c4 10 add $0x10,%esp +80102ee4: c9 leave +80102ee5: c3 ret +80102ee6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102eed: 8d 76 00 lea 0x0(%esi),%esi + +80102ef0 : + +// called at the end of each FS system call. +// commits if this was the last outstanding operation. +void +end_op(void) +{ +80102ef0: 55 push %ebp +80102ef1: 89 e5 mov %esp,%ebp +80102ef3: 57 push %edi +80102ef4: 56 push %esi +80102ef5: 53 push %ebx +80102ef6: 83 ec 18 sub $0x18,%esp + int do_commit = 0; + + acquire(&log.lock); +80102ef9: 68 c0 16 11 80 push $0x801116c0 +80102efe: e8 fd 17 00 00 call 80104700 + log.outstanding -= 1; +80102f03: a1 fc 16 11 80 mov 0x801116fc,%eax + if(log.committing) +80102f08: 8b 35 00 17 11 80 mov 0x80111700,%esi +80102f0e: 83 c4 10 add $0x10,%esp + log.outstanding -= 1; +80102f11: 8d 58 ff lea -0x1(%eax),%ebx +80102f14: 89 1d fc 16 11 80 mov %ebx,0x801116fc + if(log.committing) +80102f1a: 85 f6 test %esi,%esi +80102f1c: 0f 85 22 01 00 00 jne 80103044 + panic("log.committing"); + if(log.outstanding == 0){ +80102f22: 85 db test %ebx,%ebx +80102f24: 0f 85 f6 00 00 00 jne 80103020 + do_commit = 1; + log.committing = 1; +80102f2a: c7 05 00 17 11 80 01 movl $0x1,0x80111700 +80102f31: 00 00 00 + // begin_op() may be waiting for log space, + // and decrementing log.outstanding has decreased + // the amount of reserved space. + wakeup(&log); + } + release(&log.lock); +80102f34: 83 ec 0c sub $0xc,%esp +80102f37: 68 c0 16 11 80 push $0x801116c0 +80102f3c: e8 5f 17 00 00 call 801046a0 +} + +static void +commit() +{ + if (log.lh.n > 0) { +80102f41: 8b 0d 08 17 11 80 mov 0x80111708,%ecx +80102f47: 83 c4 10 add $0x10,%esp +80102f4a: 85 c9 test %ecx,%ecx +80102f4c: 7f 42 jg 80102f90 + acquire(&log.lock); +80102f4e: 83 ec 0c sub $0xc,%esp +80102f51: 68 c0 16 11 80 push $0x801116c0 +80102f56: e8 a5 17 00 00 call 80104700 + wakeup(&log); +80102f5b: c7 04 24 c0 16 11 80 movl $0x801116c0,(%esp) + log.committing = 0; +80102f62: c7 05 00 17 11 80 00 movl $0x0,0x80111700 +80102f69: 00 00 00 + wakeup(&log); +80102f6c: e8 ef 12 00 00 call 80104260 + release(&log.lock); +80102f71: c7 04 24 c0 16 11 80 movl $0x801116c0,(%esp) +80102f78: e8 23 17 00 00 call 801046a0 +80102f7d: 83 c4 10 add $0x10,%esp +} +80102f80: 8d 65 f4 lea -0xc(%ebp),%esp +80102f83: 5b pop %ebx +80102f84: 5e pop %esi +80102f85: 5f pop %edi +80102f86: 5d pop %ebp +80102f87: c3 ret +80102f88: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80102f8f: 90 nop + struct buf *to = bread(log.dev, log.start+tail+1); // log block +80102f90: a1 f4 16 11 80 mov 0x801116f4,%eax +80102f95: 83 ec 08 sub $0x8,%esp +80102f98: 01 d8 add %ebx,%eax +80102f9a: 83 c0 01 add $0x1,%eax +80102f9d: 50 push %eax +80102f9e: ff 35 04 17 11 80 push 0x80111704 +80102fa4: e8 27 d1 ff ff call 801000d0 +80102fa9: 89 c6 mov %eax,%esi + struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block +80102fab: 58 pop %eax +80102fac: 5a pop %edx +80102fad: ff 34 9d 0c 17 11 80 push -0x7feee8f4(,%ebx,4) +80102fb4: ff 35 04 17 11 80 push 0x80111704 + for (tail = 0; tail < log.lh.n; tail++) { +80102fba: 83 c3 01 add $0x1,%ebx + struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block +80102fbd: e8 0e d1 ff ff call 801000d0 + memmove(to->data, from->data, BSIZE); +80102fc2: 83 c4 0c add $0xc,%esp + struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block +80102fc5: 89 c7 mov %eax,%edi + memmove(to->data, from->data, BSIZE); +80102fc7: 8d 40 5c lea 0x5c(%eax),%eax +80102fca: 68 00 02 00 00 push $0x200 +80102fcf: 50 push %eax +80102fd0: 8d 46 5c lea 0x5c(%esi),%eax +80102fd3: 50 push %eax +80102fd4: e8 87 18 00 00 call 80104860 + bwrite(to); // write the log +80102fd9: 89 34 24 mov %esi,(%esp) +80102fdc: e8 cf d1 ff ff call 801001b0 + brelse(from); +80102fe1: 89 3c 24 mov %edi,(%esp) +80102fe4: e8 07 d2 ff ff call 801001f0 + brelse(to); +80102fe9: 89 34 24 mov %esi,(%esp) +80102fec: e8 ff d1 ff ff call 801001f0 + for (tail = 0; tail < log.lh.n; tail++) { +80102ff1: 83 c4 10 add $0x10,%esp +80102ff4: 3b 1d 08 17 11 80 cmp 0x80111708,%ebx +80102ffa: 7c 94 jl 80102f90 + write_log(); // Write modified blocks from cache to log + write_head(); // Write header to disk -- the real commit +80102ffc: e8 7f fd ff ff call 80102d80 + install_trans(); // Now install writes to home locations +80103001: e8 da fc ff ff call 80102ce0 + log.lh.n = 0; +80103006: c7 05 08 17 11 80 00 movl $0x0,0x80111708 +8010300d: 00 00 00 + write_head(); // Erase the transaction from the log +80103010: e8 6b fd ff ff call 80102d80 +80103015: e9 34 ff ff ff jmp 80102f4e +8010301a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + wakeup(&log); +80103020: 83 ec 0c sub $0xc,%esp +80103023: 68 c0 16 11 80 push $0x801116c0 +80103028: e8 33 12 00 00 call 80104260 + release(&log.lock); +8010302d: c7 04 24 c0 16 11 80 movl $0x801116c0,(%esp) +80103034: e8 67 16 00 00 call 801046a0 +80103039: 83 c4 10 add $0x10,%esp +} +8010303c: 8d 65 f4 lea -0xc(%ebp),%esp +8010303f: 5b pop %ebx +80103040: 5e pop %esi +80103041: 5f pop %edi +80103042: 5d pop %ebp +80103043: c3 ret + panic("log.committing"); +80103044: 83 ec 0c sub $0xc,%esp +80103047: 68 84 78 10 80 push $0x80107884 +8010304c: e8 3f d3 ff ff call 80100390 +80103051: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103058: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010305f: 90 nop + +80103060 : +// modify bp->data[] +// log_write(bp) +// brelse(bp) +void +log_write(struct buf *b) +{ +80103060: 55 push %ebp +80103061: 89 e5 mov %esp,%ebp +80103063: 53 push %ebx +80103064: 83 ec 04 sub $0x4,%esp + int i; + + if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1) +80103067: 8b 15 08 17 11 80 mov 0x80111708,%edx +{ +8010306d: 8b 5d 08 mov 0x8(%ebp),%ebx + if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1) +80103070: 83 fa 1d cmp $0x1d,%edx +80103073: 0f 8f 85 00 00 00 jg 801030fe +80103079: a1 f8 16 11 80 mov 0x801116f8,%eax +8010307e: 83 e8 01 sub $0x1,%eax +80103081: 39 c2 cmp %eax,%edx +80103083: 7d 79 jge 801030fe + panic("too big a transaction"); + if (log.outstanding < 1) +80103085: a1 fc 16 11 80 mov 0x801116fc,%eax +8010308a: 85 c0 test %eax,%eax +8010308c: 7e 7d jle 8010310b + panic("log_write outside of trans"); + + acquire(&log.lock); +8010308e: 83 ec 0c sub $0xc,%esp +80103091: 68 c0 16 11 80 push $0x801116c0 +80103096: e8 65 16 00 00 call 80104700 + for (i = 0; i < log.lh.n; i++) { +8010309b: 8b 15 08 17 11 80 mov 0x80111708,%edx +801030a1: 83 c4 10 add $0x10,%esp +801030a4: 85 d2 test %edx,%edx +801030a6: 7e 4a jle 801030f2 + if (log.lh.block[i] == b->blockno) // log absorbtion +801030a8: 8b 4b 08 mov 0x8(%ebx),%ecx + for (i = 0; i < log.lh.n; i++) { +801030ab: 31 c0 xor %eax,%eax +801030ad: eb 08 jmp 801030b7 +801030af: 90 nop +801030b0: 83 c0 01 add $0x1,%eax +801030b3: 39 c2 cmp %eax,%edx +801030b5: 74 29 je 801030e0 + if (log.lh.block[i] == b->blockno) // log absorbtion +801030b7: 39 0c 85 0c 17 11 80 cmp %ecx,-0x7feee8f4(,%eax,4) +801030be: 75 f0 jne 801030b0 + break; + } + log.lh.block[i] = b->blockno; +801030c0: 89 0c 85 0c 17 11 80 mov %ecx,-0x7feee8f4(,%eax,4) + if (i == log.lh.n) + log.lh.n++; + b->flags |= B_DIRTY; // prevent eviction +801030c7: 83 0b 04 orl $0x4,(%ebx) + release(&log.lock); +} +801030ca: 8b 5d fc mov -0x4(%ebp),%ebx + release(&log.lock); +801030cd: c7 45 08 c0 16 11 80 movl $0x801116c0,0x8(%ebp) +} +801030d4: c9 leave + release(&log.lock); +801030d5: e9 c6 15 00 00 jmp 801046a0 +801030da: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + log.lh.block[i] = b->blockno; +801030e0: 89 0c 95 0c 17 11 80 mov %ecx,-0x7feee8f4(,%edx,4) + log.lh.n++; +801030e7: 83 c2 01 add $0x1,%edx +801030ea: 89 15 08 17 11 80 mov %edx,0x80111708 +801030f0: eb d5 jmp 801030c7 + log.lh.block[i] = b->blockno; +801030f2: 8b 43 08 mov 0x8(%ebx),%eax +801030f5: a3 0c 17 11 80 mov %eax,0x8011170c + if (i == log.lh.n) +801030fa: 75 cb jne 801030c7 +801030fc: eb e9 jmp 801030e7 + panic("too big a transaction"); +801030fe: 83 ec 0c sub $0xc,%esp +80103101: 68 93 78 10 80 push $0x80107893 +80103106: e8 85 d2 ff ff call 80100390 + panic("log_write outside of trans"); +8010310b: 83 ec 0c sub $0xc,%esp +8010310e: 68 a9 78 10 80 push $0x801078a9 +80103113: e8 78 d2 ff ff call 80100390 +80103118: 66 90 xchg %ax,%ax +8010311a: 66 90 xchg %ax,%ax +8010311c: 66 90 xchg %ax,%ax +8010311e: 66 90 xchg %ax,%ax + +80103120 : + lapicinit(); + mpmain(); +} + +// Common CPU setup code. +static void mpmain(void) { +80103120: 55 push %ebp +80103121: 89 e5 mov %esp,%ebp +80103123: 53 push %ebx +80103124: 83 ec 04 sub $0x4,%esp + cprintf("cpu%d: starting %d\n", cpuid(), cpuid()); +80103127: e8 84 09 00 00 call 80103ab0 +8010312c: 89 c3 mov %eax,%ebx +8010312e: e8 7d 09 00 00 call 80103ab0 +80103133: 83 ec 04 sub $0x4,%esp +80103136: 53 push %ebx +80103137: 50 push %eax +80103138: 68 c4 78 10 80 push $0x801078c4 +8010313d: e8 6e d5 ff ff call 801006b0 + idtinit(); // load idt register +80103142: e8 b9 29 00 00 call 80105b00 + xchg(&(mycpu()->started), 1); // tell startothers() we're up +80103147: e8 04 09 00 00 call 80103a50 +8010314c: 89 c2 mov %eax,%edx + +static inline uint xchg(volatile uint *addr, uint newval) { + uint result; + + // The + in "+m" denotes a read-modify-write operand. + asm volatile ("lock; xchgl %0, %1" : +8010314e: b8 01 00 00 00 mov $0x1,%eax +80103153: f0 87 82 a0 00 00 00 lock xchg %eax,0xa0(%edx) + scheduler(); // start running processes +8010315a: e8 31 0c 00 00 call 80103d90 +8010315f: 90 nop + +80103160 : +static void mpenter(void) { +80103160: 55 push %ebp +80103161: 89 e5 mov %esp,%ebp +80103163: 83 ec 08 sub $0x8,%esp + switchkvm(); +80103166: e8 85 3a 00 00 call 80106bf0 + seginit(); +8010316b: e8 f0 39 00 00 call 80106b60 + lapicinit(); +80103170: e8 9b f7 ff ff call 80102910 + mpmain(); +80103175: e8 a6 ff ff ff call 80103120 +8010317a: 66 90 xchg %ax,%ax +8010317c: 66 90 xchg %ax,%ax +8010317e: 66 90 xchg %ax,%ax + +80103180
: +int main(void) { +80103180: 8d 4c 24 04 lea 0x4(%esp),%ecx +80103184: 83 e4 f0 and $0xfffffff0,%esp +80103187: ff 71 fc push -0x4(%ecx) +8010318a: 55 push %ebp +8010318b: 89 e5 mov %esp,%ebp +8010318d: 53 push %ebx +8010318e: 51 push %ecx + kinit1(end, P2V(4 * 1024 * 1024)); // phys page allocator +8010318f: 83 ec 08 sub $0x8,%esp +80103192: 68 00 00 40 80 push $0x80400000 +80103197: 68 f0 54 11 80 push $0x801154f0 +8010319c: e8 8f f5 ff ff call 80102730 + kvmalloc(); // kernel page table +801031a1: e8 3a 3f 00 00 call 801070e0 + mpinit(); // detect other processors +801031a6: e8 85 01 00 00 call 80103330 + lapicinit(); // interrupt controller +801031ab: e8 60 f7 ff ff call 80102910 + seginit(); // segment descriptors +801031b0: e8 ab 39 00 00 call 80106b60 + picinit(); // disable pic +801031b5: e8 76 03 00 00 call 80103530 + ioapicinit(); // another interrupt controller +801031ba: e8 31 f3 ff ff call 801024f0 + consoleinit(); // console hardware +801031bf: e8 0c d9 ff ff call 80100ad0 + uartinit(); // serial port +801031c4: e8 27 2c 00 00 call 80105df0 + pinit(); // process table +801031c9: e8 62 08 00 00 call 80103a30 + tvinit(); // trap vectors +801031ce: e8 ad 28 00 00 call 80105a80 + binit(); // buffer cache +801031d3: e8 68 ce ff ff call 80100040 + fileinit(); // file table +801031d8: e8 53 dd ff ff call 80100f30 + ideinit(); // disk +801031dd: e8 fe f0 ff ff call 801022e0 + + // Write entry code to unused memory at 0x7000. + // The linker has placed the image of entryother.S in + // _binary_entryother_start. + code = P2V(0x7000); + memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); +801031e2: 83 c4 0c add $0xc,%esp +801031e5: 68 7a 00 00 00 push $0x7a +801031ea: 68 8c a4 10 80 push $0x8010a48c +801031ef: 68 00 70 00 80 push $0x80007000 +801031f4: e8 67 16 00 00 call 80104860 + + for (c = cpus; c < cpus + ncpu; c++) { +801031f9: 83 c4 10 add $0x10,%esp +801031fc: 69 05 a4 17 11 80 b0 imul $0xb0,0x801117a4,%eax +80103203: 00 00 00 +80103206: 05 c0 17 11 80 add $0x801117c0,%eax +8010320b: 3d c0 17 11 80 cmp $0x801117c0,%eax +80103210: 76 7e jbe 80103290 +80103212: bb c0 17 11 80 mov $0x801117c0,%ebx +80103217: eb 20 jmp 80103239 +80103219: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103220: 69 05 a4 17 11 80 b0 imul $0xb0,0x801117a4,%eax +80103227: 00 00 00 +8010322a: 81 c3 b0 00 00 00 add $0xb0,%ebx +80103230: 05 c0 17 11 80 add $0x801117c0,%eax +80103235: 39 c3 cmp %eax,%ebx +80103237: 73 57 jae 80103290 + if (c == mycpu()) { // We've started already. +80103239: e8 12 08 00 00 call 80103a50 +8010323e: 39 c3 cmp %eax,%ebx +80103240: 74 de je 80103220 + } + + // Tell entryother.S what stack to use, where to enter, and what + // pgdir to use. We cannot use kpgdir yet, because the AP processor + // is running in low memory, so we use entrypgdir for the APs too. + stack = kalloc(); +80103242: e8 59 f5 ff ff call 801027a0 + *(void**)(code - 4) = stack + KSTACKSIZE; + *(void(**)(void))(code - 8) = mpenter; + *(int**)(code - 12) = (void *) V2P(entrypgdir); + + lapicstartap(c->apicid, V2P(code)); +80103247: 83 ec 08 sub $0x8,%esp + *(void(**)(void))(code - 8) = mpenter; +8010324a: c7 05 f8 6f 00 80 60 movl $0x80103160,0x80006ff8 +80103251: 31 10 80 + *(int**)(code - 12) = (void *) V2P(entrypgdir); +80103254: c7 05 f4 6f 00 80 00 movl $0x109000,0x80006ff4 +8010325b: 90 10 00 + *(void**)(code - 4) = stack + KSTACKSIZE; +8010325e: 05 00 10 00 00 add $0x1000,%eax +80103263: a3 fc 6f 00 80 mov %eax,0x80006ffc + lapicstartap(c->apicid, V2P(code)); +80103268: 0f b6 03 movzbl (%ebx),%eax +8010326b: 68 00 70 00 00 push $0x7000 +80103270: 50 push %eax +80103271: e8 ea f7 ff ff call 80102a60 + + // wait for cpu to finish mpmain() + while (c->started == 0) { +80103276: 83 c4 10 add $0x10,%esp +80103279: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103280: 8b 83 a0 00 00 00 mov 0xa0(%ebx),%eax +80103286: 85 c0 test %eax,%eax +80103288: 74 f6 je 80103280 +8010328a: eb 94 jmp 80103220 +8010328c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + kinit2(P2V(4 * 1024 * 1024), P2V(PHYSTOP)); // must come after startothers() +80103290: 83 ec 08 sub $0x8,%esp +80103293: 68 00 00 00 8e push $0x8e000000 +80103298: 68 00 00 40 80 push $0x80400000 +8010329d: e8 2e f4 ff ff call 801026d0 + userinit(); // first user process +801032a2: e8 59 08 00 00 call 80103b00 + mpmain(); // finish this processor's setup +801032a7: e8 74 fe ff ff call 80103120 +801032ac: 66 90 xchg %ax,%ax +801032ae: 66 90 xchg %ax,%ax + +801032b0 : + } + return sum; +} + +// Look for an MP structure in the len bytes at addr. +static struct mp*mpsearch1(uint a, int len) { +801032b0: 55 push %ebp +801032b1: 89 e5 mov %esp,%ebp +801032b3: 57 push %edi +801032b4: 56 push %esi + uchar *e, *p, *addr; + + addr = P2V(a); +801032b5: 8d b0 00 00 00 80 lea -0x80000000(%eax),%esi +static struct mp*mpsearch1(uint a, int len) { +801032bb: 53 push %ebx + e = addr + len; +801032bc: 8d 1c 16 lea (%esi,%edx,1),%ebx +static struct mp*mpsearch1(uint a, int len) { +801032bf: 83 ec 0c sub $0xc,%esp + for (p = addr; p < e; p += sizeof(struct mp)) { +801032c2: 39 de cmp %ebx,%esi +801032c4: 72 10 jb 801032d6 +801032c6: eb 50 jmp 80103318 +801032c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801032cf: 90 nop +801032d0: 89 fe mov %edi,%esi +801032d2: 39 fb cmp %edi,%ebx +801032d4: 76 42 jbe 80103318 + if (memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0) { +801032d6: 83 ec 04 sub $0x4,%esp +801032d9: 8d 7e 10 lea 0x10(%esi),%edi +801032dc: 6a 04 push $0x4 +801032de: 68 d8 78 10 80 push $0x801078d8 +801032e3: 56 push %esi +801032e4: e8 27 15 00 00 call 80104810 +801032e9: 83 c4 10 add $0x10,%esp +801032ec: 85 c0 test %eax,%eax +801032ee: 75 e0 jne 801032d0 +801032f0: 89 f2 mov %esi,%edx +801032f2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + sum += addr[i]; +801032f8: 0f b6 0a movzbl (%edx),%ecx + for (i = 0; i < len; i++) { +801032fb: 83 c2 01 add $0x1,%edx + sum += addr[i]; +801032fe: 01 c8 add %ecx,%eax + for (i = 0; i < len; i++) { +80103300: 39 fa cmp %edi,%edx +80103302: 75 f4 jne 801032f8 + if (memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0) { +80103304: 84 c0 test %al,%al +80103306: 75 c8 jne 801032d0 + return (struct mp*)p; + } + } + return 0; +} +80103308: 8d 65 f4 lea -0xc(%ebp),%esp +8010330b: 89 f0 mov %esi,%eax +8010330d: 5b pop %ebx +8010330e: 5e pop %esi +8010330f: 5f pop %edi +80103310: 5d pop %ebp +80103311: c3 ret +80103312: 8d b6 00 00 00 00 lea 0x0(%esi),%esi +80103318: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; +8010331b: 31 f6 xor %esi,%esi +} +8010331d: 5b pop %ebx +8010331e: 89 f0 mov %esi,%eax +80103320: 5e pop %esi +80103321: 5f pop %edi +80103322: 5d pop %ebp +80103323: c3 ret +80103324: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010332b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010332f: 90 nop + +80103330 : + } + *pmp = mp; + return conf; +} + +void mpinit(void) { +80103330: 55 push %ebp +80103331: 89 e5 mov %esp,%ebp +80103333: 57 push %edi +80103334: 56 push %esi +80103335: 53 push %ebx +80103336: 83 ec 1c sub $0x1c,%esp + if ((p = ((bda[0x0F] << 8) | bda[0x0E]) << 4)) { +80103339: 0f b6 05 0f 04 00 80 movzbl 0x8000040f,%eax +80103340: 0f b6 15 0e 04 00 80 movzbl 0x8000040e,%edx +80103347: c1 e0 08 shl $0x8,%eax +8010334a: 09 d0 or %edx,%eax +8010334c: c1 e0 04 shl $0x4,%eax +8010334f: 75 1b jne 8010336c + p = ((bda[0x14] << 8) | bda[0x13]) * 1024; +80103351: 0f b6 05 14 04 00 80 movzbl 0x80000414,%eax +80103358: 0f b6 15 13 04 00 80 movzbl 0x80000413,%edx +8010335f: c1 e0 08 shl $0x8,%eax +80103362: 09 d0 or %edx,%eax +80103364: c1 e0 0a shl $0xa,%eax + if ((mp = mpsearch1(p - 1024, 1024))) { +80103367: 2d 00 04 00 00 sub $0x400,%eax + if ((mp = mpsearch1(p, 1024))) { +8010336c: ba 00 04 00 00 mov $0x400,%edx +80103371: e8 3a ff ff ff call 801032b0 +80103376: 89 c3 mov %eax,%ebx +80103378: 85 c0 test %eax,%eax +8010337a: 0f 84 40 01 00 00 je 801034c0 + if ((mp = mpsearch()) == 0 || mp->physaddr == 0) { +80103380: 8b 73 04 mov 0x4(%ebx),%esi +80103383: 85 f6 test %esi,%esi +80103385: 0f 84 25 01 00 00 je 801034b0 + if (memcmp(conf, "PCMP", 4) != 0) { +8010338b: 83 ec 04 sub $0x4,%esp + conf = (struct mpconf*) P2V((uint) mp->physaddr); +8010338e: 8d 86 00 00 00 80 lea -0x80000000(%esi),%eax + if (memcmp(conf, "PCMP", 4) != 0) { +80103394: 6a 04 push $0x4 +80103396: 68 dd 78 10 80 push $0x801078dd +8010339b: 50 push %eax + conf = (struct mpconf*) P2V((uint) mp->physaddr); +8010339c: 89 45 e4 mov %eax,-0x1c(%ebp) + if (memcmp(conf, "PCMP", 4) != 0) { +8010339f: e8 6c 14 00 00 call 80104810 +801033a4: 83 c4 10 add $0x10,%esp +801033a7: 85 c0 test %eax,%eax +801033a9: 0f 85 01 01 00 00 jne 801034b0 + if (conf->version != 1 && conf->version != 4) { +801033af: 0f b6 86 06 00 00 80 movzbl -0x7ffffffa(%esi),%eax +801033b6: 3c 01 cmp $0x1,%al +801033b8: 74 08 je 801033c2 +801033ba: 3c 04 cmp $0x4,%al +801033bc: 0f 85 ee 00 00 00 jne 801034b0 + if (sum((uchar*)conf, conf->length) != 0) { +801033c2: 0f b7 96 04 00 00 80 movzwl -0x7ffffffc(%esi),%edx + for (i = 0; i < len; i++) { +801033c9: 66 85 d2 test %dx,%dx +801033cc: 74 22 je 801033f0 +801033ce: 8d 3c 32 lea (%edx,%esi,1),%edi +801033d1: 89 f0 mov %esi,%eax + sum = 0; +801033d3: 31 d2 xor %edx,%edx +801033d5: 8d 76 00 lea 0x0(%esi),%esi + sum += addr[i]; +801033d8: 0f b6 88 00 00 00 80 movzbl -0x80000000(%eax),%ecx + for (i = 0; i < len; i++) { +801033df: 83 c0 01 add $0x1,%eax + sum += addr[i]; +801033e2: 01 ca add %ecx,%edx + for (i = 0; i < len; i++) { +801033e4: 39 c7 cmp %eax,%edi +801033e6: 75 f0 jne 801033d8 + if (sum((uchar*)conf, conf->length) != 0) { +801033e8: 84 d2 test %dl,%dl +801033ea: 0f 85 c0 00 00 00 jne 801034b0 + + if ((conf = mpconfig(&mp)) == 0) { + panic("Expect to run on an SMP"); + } + ismp = 1; + lapic = (uint*)conf->lapicaddr; +801033f0: 8b 86 24 00 00 80 mov -0x7fffffdc(%esi),%eax +801033f6: a3 a0 16 11 80 mov %eax,0x801116a0 + for (p = (uchar*)(conf + 1), e = (uchar*)conf + conf->length; p < e;) { +801033fb: 0f b7 96 04 00 00 80 movzwl -0x7ffffffc(%esi),%edx +80103402: 8d 86 2c 00 00 80 lea -0x7fffffd4(%esi),%eax + ismp = 1; +80103408: be 01 00 00 00 mov $0x1,%esi + for (p = (uchar*)(conf + 1), e = (uchar*)conf + conf->length; p < e;) { +8010340d: 03 55 e4 add -0x1c(%ebp),%edx +80103410: 89 5d e4 mov %ebx,-0x1c(%ebp) +80103413: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80103417: 90 nop +80103418: 39 d0 cmp %edx,%eax +8010341a: 73 15 jae 80103431 + switch (*p) { +8010341c: 0f b6 08 movzbl (%eax),%ecx +8010341f: 80 f9 02 cmp $0x2,%cl +80103422: 74 4c je 80103470 +80103424: 77 3a ja 80103460 +80103426: 84 c9 test %cl,%cl +80103428: 74 56 je 80103480 + p += sizeof(struct mpioapic); + continue; + case MPBUS: + case MPIOINTR: + case MPLINTR: + p += 8; +8010342a: 83 c0 08 add $0x8,%eax + for (p = (uchar*)(conf + 1), e = (uchar*)conf + conf->length; p < e;) { +8010342d: 39 d0 cmp %edx,%eax +8010342f: 72 eb jb 8010341c + default: + ismp = 0; + break; + } + } + if (!ismp) { +80103431: 8b 5d e4 mov -0x1c(%ebp),%ebx +80103434: 85 f6 test %esi,%esi +80103436: 0f 84 d9 00 00 00 je 80103515 + panic("Didn't find a suitable machine"); + } + + if (mp->imcrp) { +8010343c: 80 7b 0c 00 cmpb $0x0,0xc(%ebx) +80103440: 74 15 je 80103457 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80103442: b8 70 00 00 00 mov $0x70,%eax +80103447: ba 22 00 00 00 mov $0x22,%edx +8010344c: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +8010344d: ba 23 00 00 00 mov $0x23,%edx +80103452: ec in (%dx),%al + // Bochs doesn't support IMCR, so this doesn't run on Bochs. + // But it would on real hardware. + outb(0x22, 0x70); // Select IMCR + outb(0x23, inb(0x23) | 1); // Mask external interrupts. +80103453: 83 c8 01 or $0x1,%eax + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80103456: ee out %al,(%dx) + } +} +80103457: 8d 65 f4 lea -0xc(%ebp),%esp +8010345a: 5b pop %ebx +8010345b: 5e pop %esi +8010345c: 5f pop %edi +8010345d: 5d pop %ebp +8010345e: c3 ret +8010345f: 90 nop + switch (*p) { +80103460: 83 e9 03 sub $0x3,%ecx +80103463: 80 f9 01 cmp $0x1,%cl +80103466: 76 c2 jbe 8010342a +80103468: 31 f6 xor %esi,%esi +8010346a: eb ac jmp 80103418 +8010346c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + ioapicid = ioapic->apicno; +80103470: 0f b6 48 01 movzbl 0x1(%eax),%ecx + p += sizeof(struct mpioapic); +80103474: 83 c0 08 add $0x8,%eax + ioapicid = ioapic->apicno; +80103477: 88 0d a0 17 11 80 mov %cl,0x801117a0 + continue; +8010347d: eb 99 jmp 80103418 +8010347f: 90 nop + if (ncpu < NCPU) { +80103480: 8b 0d a4 17 11 80 mov 0x801117a4,%ecx +80103486: 83 f9 07 cmp $0x7,%ecx +80103489: 7f 19 jg 801034a4 + cpus[ncpu].apicid = proc->apicid; // apicid may differ from ncpu +8010348b: 69 f9 b0 00 00 00 imul $0xb0,%ecx,%edi +80103491: 0f b6 58 01 movzbl 0x1(%eax),%ebx + ncpu++; +80103495: 83 c1 01 add $0x1,%ecx +80103498: 89 0d a4 17 11 80 mov %ecx,0x801117a4 + cpus[ncpu].apicid = proc->apicid; // apicid may differ from ncpu +8010349e: 88 9f c0 17 11 80 mov %bl,-0x7feee840(%edi) + p += sizeof(struct mpproc); +801034a4: 83 c0 14 add $0x14,%eax + continue; +801034a7: e9 6c ff ff ff jmp 80103418 +801034ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + panic("Expect to run on an SMP"); +801034b0: 83 ec 0c sub $0xc,%esp +801034b3: 68 e2 78 10 80 push $0x801078e2 +801034b8: e8 d3 ce ff ff call 80100390 +801034bd: 8d 76 00 lea 0x0(%esi),%esi +void mpinit(void) { +801034c0: bb 00 00 0f 80 mov $0x800f0000,%ebx +801034c5: eb 13 jmp 801034da +801034c7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801034ce: 66 90 xchg %ax,%ax + for (p = addr; p < e; p += sizeof(struct mp)) { +801034d0: 89 f3 mov %esi,%ebx +801034d2: 81 fe 00 00 10 80 cmp $0x80100000,%esi +801034d8: 74 d6 je 801034b0 + if (memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0) { +801034da: 83 ec 04 sub $0x4,%esp +801034dd: 8d 73 10 lea 0x10(%ebx),%esi +801034e0: 6a 04 push $0x4 +801034e2: 68 d8 78 10 80 push $0x801078d8 +801034e7: 53 push %ebx +801034e8: e8 23 13 00 00 call 80104810 +801034ed: 83 c4 10 add $0x10,%esp +801034f0: 85 c0 test %eax,%eax +801034f2: 75 dc jne 801034d0 +801034f4: 89 da mov %ebx,%edx +801034f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801034fd: 8d 76 00 lea 0x0(%esi),%esi + sum += addr[i]; +80103500: 0f b6 0a movzbl (%edx),%ecx + for (i = 0; i < len; i++) { +80103503: 83 c2 01 add $0x1,%edx + sum += addr[i]; +80103506: 01 c8 add %ecx,%eax + for (i = 0; i < len; i++) { +80103508: 39 d6 cmp %edx,%esi +8010350a: 75 f4 jne 80103500 + if (memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0) { +8010350c: 84 c0 test %al,%al +8010350e: 75 c0 jne 801034d0 +80103510: e9 6b fe ff ff jmp 80103380 + panic("Didn't find a suitable machine"); +80103515: 83 ec 0c sub $0xc,%esp +80103518: 68 fc 78 10 80 push $0x801078fc +8010351d: e8 6e ce ff ff call 80100390 +80103522: 66 90 xchg %ax,%ax +80103524: 66 90 xchg %ax,%ax +80103526: 66 90 xchg %ax,%ax +80103528: 66 90 xchg %ax,%ax +8010352a: 66 90 xchg %ax,%ax +8010352c: 66 90 xchg %ax,%ax +8010352e: 66 90 xchg %ax,%ax + +80103530 : +80103530: b8 ff ff ff ff mov $0xffffffff,%eax +80103535: ba 21 00 00 00 mov $0x21,%edx +8010353a: ee out %al,(%dx) +8010353b: ba a1 00 00 00 mov $0xa1,%edx +80103540: ee out %al,(%dx) +// Don't use the 8259A interrupt controllers. Xv6 assumes SMP hardware. +void picinit(void) { + // mask all interrupts + outb(IO_PIC1 + 1, 0xFF); + outb(IO_PIC2 + 1, 0xFF); +} +80103541: c3 ret +80103542: 66 90 xchg %ax,%ax +80103544: 66 90 xchg %ax,%ax +80103546: 66 90 xchg %ax,%ax +80103548: 66 90 xchg %ax,%ax +8010354a: 66 90 xchg %ax,%ax +8010354c: 66 90 xchg %ax,%ax +8010354e: 66 90 xchg %ax,%ax + +80103550 : + uint nwrite; // number of bytes written + int readopen; // read fd is still open + int writeopen; // write fd is still open +}; + +void cleanuppipealloc(struct pipe *p, struct file **f0, struct file **f1) { +80103550: 55 push %ebp +80103551: 89 e5 mov %esp,%ebp +80103553: 56 push %esi +80103554: 8b 45 08 mov 0x8(%ebp),%eax +80103557: 8b 75 0c mov 0xc(%ebp),%esi +8010355a: 53 push %ebx +8010355b: 8b 5d 10 mov 0x10(%ebp),%ebx + if (p) { +8010355e: 85 c0 test %eax,%eax +80103560: 74 0c je 8010356e + kfree((char*)p); +80103562: 83 ec 0c sub $0xc,%esp +80103565: 50 push %eax +80103566: e8 75 f0 ff ff call 801025e0 +8010356b: 83 c4 10 add $0x10,%esp + } + if (*f0) { +8010356e: 8b 06 mov (%esi),%eax +80103570: 85 c0 test %eax,%eax +80103572: 74 0c je 80103580 + fileclose(*f0); +80103574: 83 ec 0c sub $0xc,%esp +80103577: 50 push %eax +80103578: e8 93 da ff ff call 80101010 +8010357d: 83 c4 10 add $0x10,%esp + } + if (*f1) { +80103580: 8b 03 mov (%ebx),%eax +80103582: 85 c0 test %eax,%eax +80103584: 74 12 je 80103598 + fileclose(*f1); +80103586: 89 45 08 mov %eax,0x8(%ebp) + } +} +80103589: 8d 65 f8 lea -0x8(%ebp),%esp +8010358c: 5b pop %ebx +8010358d: 5e pop %esi +8010358e: 5d pop %ebp + fileclose(*f1); +8010358f: e9 7c da ff ff jmp 80101010 +80103594: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +} +80103598: 8d 65 f8 lea -0x8(%ebp),%esp +8010359b: 5b pop %ebx +8010359c: 5e pop %esi +8010359d: 5d pop %ebp +8010359e: c3 ret +8010359f: 90 nop + +801035a0 : + +int pipealloc(struct file **f0, struct file **f1) { +801035a0: 55 push %ebp +801035a1: 89 e5 mov %esp,%ebp +801035a3: 57 push %edi +801035a4: 56 push %esi +801035a5: 53 push %ebx +801035a6: 83 ec 0c sub $0xc,%esp +801035a9: 8b 75 08 mov 0x8(%ebp),%esi +801035ac: 8b 7d 0c mov 0xc(%ebp),%edi + struct pipe *p; + + p = 0; + *f0 = *f1 = 0; +801035af: c7 07 00 00 00 00 movl $0x0,(%edi) +801035b5: c7 06 00 00 00 00 movl $0x0,(%esi) + if ((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) { +801035bb: e8 90 d9 ff ff call 80100f50 +801035c0: 89 06 mov %eax,(%esi) +801035c2: 85 c0 test %eax,%eax +801035c4: 0f 84 a5 00 00 00 je 8010366f +801035ca: e8 81 d9 ff ff call 80100f50 +801035cf: 89 07 mov %eax,(%edi) +801035d1: 85 c0 test %eax,%eax +801035d3: 0f 84 84 00 00 00 je 8010365d + cleanuppipealloc(p, f0, f1); + return -1; + } + if ((p = (struct pipe*)kalloc()) == 0) { +801035d9: e8 c2 f1 ff ff call 801027a0 +801035de: 89 c3 mov %eax,%ebx +801035e0: 85 c0 test %eax,%eax +801035e2: 0f 84 a0 00 00 00 je 80103688 + cleanuppipealloc(p, f0, f1); + return -1; + } + p->readopen = 1; +801035e8: c7 80 3c 02 00 00 01 movl $0x1,0x23c(%eax) +801035ef: 00 00 00 + p->writeopen = 1; + p->nwrite = 0; + p->nread = 0; + initlock(&p->lock, "pipe"); +801035f2: 83 ec 08 sub $0x8,%esp + p->writeopen = 1; +801035f5: c7 80 40 02 00 00 01 movl $0x1,0x240(%eax) +801035fc: 00 00 00 + p->nwrite = 0; +801035ff: c7 80 38 02 00 00 00 movl $0x0,0x238(%eax) +80103606: 00 00 00 + p->nread = 0; +80103609: c7 80 34 02 00 00 00 movl $0x0,0x234(%eax) +80103610: 00 00 00 + initlock(&p->lock, "pipe"); +80103613: 68 1b 79 10 80 push $0x8010791b +80103618: 50 push %eax +80103619: e8 12 0f 00 00 call 80104530 + (*f0)->type = FD_PIPE; +8010361e: 8b 06 mov (%esi),%eax + (*f0)->pipe = p; + (*f1)->type = FD_PIPE; + (*f1)->readable = 0; + (*f1)->writable = 1; + (*f1)->pipe = p; + return 0; +80103620: 83 c4 10 add $0x10,%esp + (*f0)->type = FD_PIPE; +80103623: c7 00 01 00 00 00 movl $0x1,(%eax) + (*f0)->readable = 1; +80103629: 8b 06 mov (%esi),%eax +8010362b: c6 40 08 01 movb $0x1,0x8(%eax) + (*f0)->writable = 0; +8010362f: 8b 06 mov (%esi),%eax +80103631: c6 40 09 00 movb $0x0,0x9(%eax) + (*f0)->pipe = p; +80103635: 8b 06 mov (%esi),%eax +80103637: 89 58 0c mov %ebx,0xc(%eax) + (*f1)->type = FD_PIPE; +8010363a: 8b 07 mov (%edi),%eax +8010363c: c7 00 01 00 00 00 movl $0x1,(%eax) + (*f1)->readable = 0; +80103642: 8b 07 mov (%edi),%eax +80103644: c6 40 08 00 movb $0x0,0x8(%eax) + (*f1)->writable = 1; +80103648: 8b 07 mov (%edi),%eax +8010364a: c6 40 09 01 movb $0x1,0x9(%eax) + (*f1)->pipe = p; +8010364e: 8b 07 mov (%edi),%eax +80103650: 89 58 0c mov %ebx,0xc(%eax) + return 0; +80103653: 31 c0 xor %eax,%eax +} +80103655: 8d 65 f4 lea -0xc(%ebp),%esp +80103658: 5b pop %ebx +80103659: 5e pop %esi +8010365a: 5f pop %edi +8010365b: 5d pop %ebp +8010365c: c3 ret + if (*f0) { +8010365d: 8b 06 mov (%esi),%eax +8010365f: 85 c0 test %eax,%eax +80103661: 74 1e je 80103681 + fileclose(*f0); +80103663: 83 ec 0c sub $0xc,%esp +80103666: 50 push %eax +80103667: e8 a4 d9 ff ff call 80101010 +8010366c: 83 c4 10 add $0x10,%esp + if (*f1) { +8010366f: 8b 07 mov (%edi),%eax +80103671: 85 c0 test %eax,%eax +80103673: 74 0c je 80103681 + fileclose(*f1); +80103675: 83 ec 0c sub $0xc,%esp +80103678: 50 push %eax +80103679: e8 92 d9 ff ff call 80101010 +8010367e: 83 c4 10 add $0x10,%esp + return -1; +80103681: b8 ff ff ff ff mov $0xffffffff,%eax +80103686: eb cd jmp 80103655 + if (*f0) { +80103688: 8b 06 mov (%esi),%eax +8010368a: 85 c0 test %eax,%eax +8010368c: 75 d5 jne 80103663 +8010368e: eb df jmp 8010366f + +80103690 : + +void pipeclose(struct pipe *p, int writable) { +80103690: 55 push %ebp +80103691: 89 e5 mov %esp,%ebp +80103693: 56 push %esi +80103694: 53 push %ebx +80103695: 8b 5d 08 mov 0x8(%ebp),%ebx +80103698: 8b 75 0c mov 0xc(%ebp),%esi + acquire(&p->lock); +8010369b: 83 ec 0c sub $0xc,%esp +8010369e: 53 push %ebx +8010369f: e8 5c 10 00 00 call 80104700 + if (writable) { +801036a4: 83 c4 10 add $0x10,%esp +801036a7: 85 f6 test %esi,%esi +801036a9: 74 65 je 80103710 + p->writeopen = 0; + wakeup(&p->nread); +801036ab: 83 ec 0c sub $0xc,%esp +801036ae: 8d 83 34 02 00 00 lea 0x234(%ebx),%eax + p->writeopen = 0; +801036b4: c7 83 40 02 00 00 00 movl $0x0,0x240(%ebx) +801036bb: 00 00 00 + wakeup(&p->nread); +801036be: 50 push %eax +801036bf: e8 9c 0b 00 00 call 80104260 +801036c4: 83 c4 10 add $0x10,%esp + } + else { + p->readopen = 0; + wakeup(&p->nwrite); + } + if (p->readopen == 0 && p->writeopen == 0) { +801036c7: 8b 93 3c 02 00 00 mov 0x23c(%ebx),%edx +801036cd: 85 d2 test %edx,%edx +801036cf: 75 0a jne 801036db +801036d1: 8b 83 40 02 00 00 mov 0x240(%ebx),%eax +801036d7: 85 c0 test %eax,%eax +801036d9: 74 15 je 801036f0 + release(&p->lock); + kfree((char*)p); + } + else { + release(&p->lock); +801036db: 89 5d 08 mov %ebx,0x8(%ebp) + } +} +801036de: 8d 65 f8 lea -0x8(%ebp),%esp +801036e1: 5b pop %ebx +801036e2: 5e pop %esi +801036e3: 5d pop %ebp + release(&p->lock); +801036e4: e9 b7 0f 00 00 jmp 801046a0 +801036e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + release(&p->lock); +801036f0: 83 ec 0c sub $0xc,%esp +801036f3: 53 push %ebx +801036f4: e8 a7 0f 00 00 call 801046a0 + kfree((char*)p); +801036f9: 89 5d 08 mov %ebx,0x8(%ebp) +801036fc: 83 c4 10 add $0x10,%esp +} +801036ff: 8d 65 f8 lea -0x8(%ebp),%esp +80103702: 5b pop %ebx +80103703: 5e pop %esi +80103704: 5d pop %ebp + kfree((char*)p); +80103705: e9 d6 ee ff ff jmp 801025e0 +8010370a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + wakeup(&p->nwrite); +80103710: 83 ec 0c sub $0xc,%esp +80103713: 8d 83 38 02 00 00 lea 0x238(%ebx),%eax + p->readopen = 0; +80103719: c7 83 3c 02 00 00 00 movl $0x0,0x23c(%ebx) +80103720: 00 00 00 + wakeup(&p->nwrite); +80103723: 50 push %eax +80103724: e8 37 0b 00 00 call 80104260 +80103729: 83 c4 10 add $0x10,%esp +8010372c: eb 99 jmp 801036c7 +8010372e: 66 90 xchg %ax,%ax + +80103730 : + +int pipewrite(struct pipe *p, char *addr, int n) { +80103730: 55 push %ebp +80103731: 89 e5 mov %esp,%ebp +80103733: 57 push %edi +80103734: 56 push %esi +80103735: 53 push %ebx +80103736: 83 ec 28 sub $0x28,%esp +80103739: 8b 5d 08 mov 0x8(%ebp),%ebx + int i; + + acquire(&p->lock); +8010373c: 53 push %ebx +8010373d: e8 be 0f 00 00 call 80104700 + for (i = 0; i < n; i++) { +80103742: 8b 45 10 mov 0x10(%ebp),%eax +80103745: 83 c4 10 add $0x10,%esp +80103748: 85 c0 test %eax,%eax +8010374a: 0f 8e c0 00 00 00 jle 80103810 +80103750: 8b 45 0c mov 0xc(%ebp),%eax + while (p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full +80103753: 8b 8b 38 02 00 00 mov 0x238(%ebx),%ecx + if (p->readopen == 0 || myproc()->killed) { + release(&p->lock); + return -1; + } + wakeup(&p->nread); +80103759: 8d bb 34 02 00 00 lea 0x234(%ebx),%edi +8010375f: 89 45 e4 mov %eax,-0x1c(%ebp) +80103762: 03 45 10 add 0x10(%ebp),%eax +80103765: 89 45 e0 mov %eax,-0x20(%ebp) + while (p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full +80103768: 8b 83 34 02 00 00 mov 0x234(%ebx),%eax + sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep +8010376e: 8d b3 38 02 00 00 lea 0x238(%ebx),%esi + while (p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full +80103774: 89 ca mov %ecx,%edx +80103776: 05 00 02 00 00 add $0x200,%eax +8010377b: 39 c1 cmp %eax,%ecx +8010377d: 74 3f je 801037be +8010377f: eb 67 jmp 801037e8 +80103781: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + if (p->readopen == 0 || myproc()->killed) { +80103788: e8 43 03 00 00 call 80103ad0 +8010378d: 8b 48 24 mov 0x24(%eax),%ecx +80103790: 85 c9 test %ecx,%ecx +80103792: 75 34 jne 801037c8 + wakeup(&p->nread); +80103794: 83 ec 0c sub $0xc,%esp +80103797: 57 push %edi +80103798: e8 c3 0a 00 00 call 80104260 + sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep +8010379d: 58 pop %eax +8010379e: 5a pop %edx +8010379f: 53 push %ebx +801037a0: 56 push %esi +801037a1: e8 fa 09 00 00 call 801041a0 + while (p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full +801037a6: 8b 83 34 02 00 00 mov 0x234(%ebx),%eax +801037ac: 8b 93 38 02 00 00 mov 0x238(%ebx),%edx +801037b2: 83 c4 10 add $0x10,%esp +801037b5: 05 00 02 00 00 add $0x200,%eax +801037ba: 39 c2 cmp %eax,%edx +801037bc: 75 2a jne 801037e8 + if (p->readopen == 0 || myproc()->killed) { +801037be: 8b 83 3c 02 00 00 mov 0x23c(%ebx),%eax +801037c4: 85 c0 test %eax,%eax +801037c6: 75 c0 jne 80103788 + release(&p->lock); +801037c8: 83 ec 0c sub $0xc,%esp +801037cb: 53 push %ebx +801037cc: e8 cf 0e 00 00 call 801046a0 + return -1; +801037d1: 83 c4 10 add $0x10,%esp +801037d4: b8 ff ff ff ff mov $0xffffffff,%eax + p->data[p->nwrite++ % PIPESIZE] = addr[i]; + } + wakeup(&p->nread); //DOC: pipewrite-wakeup1 + release(&p->lock); + return n; +} +801037d9: 8d 65 f4 lea -0xc(%ebp),%esp +801037dc: 5b pop %ebx +801037dd: 5e pop %esi +801037de: 5f pop %edi +801037df: 5d pop %ebp +801037e0: c3 ret +801037e1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + p->data[p->nwrite++ % PIPESIZE] = addr[i]; +801037e8: 8b 75 e4 mov -0x1c(%ebp),%esi +801037eb: 8d 4a 01 lea 0x1(%edx),%ecx +801037ee: 81 e2 ff 01 00 00 and $0x1ff,%edx +801037f4: 89 8b 38 02 00 00 mov %ecx,0x238(%ebx) +801037fa: 0f b6 06 movzbl (%esi),%eax + for (i = 0; i < n; i++) { +801037fd: 83 c6 01 add $0x1,%esi +80103800: 89 75 e4 mov %esi,-0x1c(%ebp) + p->data[p->nwrite++ % PIPESIZE] = addr[i]; +80103803: 88 44 13 34 mov %al,0x34(%ebx,%edx,1) + for (i = 0; i < n; i++) { +80103807: 3b 75 e0 cmp -0x20(%ebp),%esi +8010380a: 0f 85 58 ff ff ff jne 80103768 + wakeup(&p->nread); //DOC: pipewrite-wakeup1 +80103810: 83 ec 0c sub $0xc,%esp +80103813: 8d 83 34 02 00 00 lea 0x234(%ebx),%eax +80103819: 50 push %eax +8010381a: e8 41 0a 00 00 call 80104260 + release(&p->lock); +8010381f: 89 1c 24 mov %ebx,(%esp) +80103822: e8 79 0e 00 00 call 801046a0 + return n; +80103827: 8b 45 10 mov 0x10(%ebp),%eax +8010382a: 83 c4 10 add $0x10,%esp +8010382d: eb aa jmp 801037d9 +8010382f: 90 nop + +80103830 : + +int piperead(struct pipe *p, char *addr, int n) { +80103830: 55 push %ebp +80103831: 89 e5 mov %esp,%ebp +80103833: 57 push %edi +80103834: 56 push %esi +80103835: 53 push %ebx +80103836: 83 ec 18 sub $0x18,%esp +80103839: 8b 75 08 mov 0x8(%ebp),%esi +8010383c: 8b 7d 0c mov 0xc(%ebp),%edi + int i; + + acquire(&p->lock); +8010383f: 56 push %esi +80103840: 8d 9e 34 02 00 00 lea 0x234(%esi),%ebx +80103846: e8 b5 0e 00 00 call 80104700 + while (p->nread == p->nwrite && p->writeopen) { //DOC: pipe-empty +8010384b: 8b 86 34 02 00 00 mov 0x234(%esi),%eax +80103851: 83 c4 10 add $0x10,%esp +80103854: 39 86 38 02 00 00 cmp %eax,0x238(%esi) +8010385a: 74 2f je 8010388b +8010385c: eb 37 jmp 80103895 +8010385e: 66 90 xchg %ax,%ax + if (myproc()->killed) { +80103860: e8 6b 02 00 00 call 80103ad0 +80103865: 8b 48 24 mov 0x24(%eax),%ecx +80103868: 85 c9 test %ecx,%ecx +8010386a: 0f 85 80 00 00 00 jne 801038f0 + release(&p->lock); + return -1; + } + sleep(&p->nread, &p->lock); //DOC: piperead-sleep +80103870: 83 ec 08 sub $0x8,%esp +80103873: 56 push %esi +80103874: 53 push %ebx +80103875: e8 26 09 00 00 call 801041a0 + while (p->nread == p->nwrite && p->writeopen) { //DOC: pipe-empty +8010387a: 8b 86 38 02 00 00 mov 0x238(%esi),%eax +80103880: 83 c4 10 add $0x10,%esp +80103883: 39 86 34 02 00 00 cmp %eax,0x234(%esi) +80103889: 75 0a jne 80103895 +8010388b: 8b 86 40 02 00 00 mov 0x240(%esi),%eax +80103891: 85 c0 test %eax,%eax +80103893: 75 cb jne 80103860 + } + for (i = 0; i < n; i++) { //DOC: piperead-copy +80103895: 8b 55 10 mov 0x10(%ebp),%edx +80103898: 31 db xor %ebx,%ebx +8010389a: 85 d2 test %edx,%edx +8010389c: 7f 20 jg 801038be +8010389e: eb 2c jmp 801038cc + if (p->nread == p->nwrite) { + break; + } + addr[i] = p->data[p->nread++ % PIPESIZE]; +801038a0: 8d 48 01 lea 0x1(%eax),%ecx +801038a3: 25 ff 01 00 00 and $0x1ff,%eax +801038a8: 89 8e 34 02 00 00 mov %ecx,0x234(%esi) +801038ae: 0f b6 44 06 34 movzbl 0x34(%esi,%eax,1),%eax +801038b3: 88 04 1f mov %al,(%edi,%ebx,1) + for (i = 0; i < n; i++) { //DOC: piperead-copy +801038b6: 83 c3 01 add $0x1,%ebx +801038b9: 39 5d 10 cmp %ebx,0x10(%ebp) +801038bc: 74 0e je 801038cc + if (p->nread == p->nwrite) { +801038be: 8b 86 34 02 00 00 mov 0x234(%esi),%eax +801038c4: 3b 86 38 02 00 00 cmp 0x238(%esi),%eax +801038ca: 75 d4 jne 801038a0 + } + wakeup(&p->nwrite); //DOC: piperead-wakeup +801038cc: 83 ec 0c sub $0xc,%esp +801038cf: 8d 86 38 02 00 00 lea 0x238(%esi),%eax +801038d5: 50 push %eax +801038d6: e8 85 09 00 00 call 80104260 + release(&p->lock); +801038db: 89 34 24 mov %esi,(%esp) +801038de: e8 bd 0d 00 00 call 801046a0 + return i; +801038e3: 83 c4 10 add $0x10,%esp +} +801038e6: 8d 65 f4 lea -0xc(%ebp),%esp +801038e9: 89 d8 mov %ebx,%eax +801038eb: 5b pop %ebx +801038ec: 5e pop %esi +801038ed: 5f pop %edi +801038ee: 5d pop %ebp +801038ef: c3 ret + release(&p->lock); +801038f0: 83 ec 0c sub $0xc,%esp + return -1; +801038f3: bb ff ff ff ff mov $0xffffffff,%ebx + release(&p->lock); +801038f8: 56 push %esi +801038f9: e8 a2 0d 00 00 call 801046a0 + return -1; +801038fe: 83 c4 10 add $0x10,%esp +} +80103901: 8d 65 f4 lea -0xc(%ebp),%esp +80103904: 89 d8 mov %ebx,%eax +80103906: 5b pop %ebx +80103907: 5e pop %esi +80103908: 5f pop %edi +80103909: 5d pop %ebp +8010390a: c3 ret +8010390b: 66 90 xchg %ax,%ax +8010390d: 66 90 xchg %ax,%ax +8010390f: 90 nop + +80103910 : + +// Look in the process table for an UNUSED proc. +// If found, change state to EMBRYO and initialize +// state required to run in the kernel. +// Otherwise return 0. +static struct proc* allocproc(void) { +80103910: 55 push %ebp +80103911: 89 e5 mov %esp,%ebp +80103913: 53 push %ebx + char *sp; + int found = 0; + + acquire(&ptable.lock); + + p = ptable.proc; +80103914: bb 74 1d 11 80 mov $0x80111d74,%ebx +static struct proc* allocproc(void) { +80103919: 83 ec 10 sub $0x10,%esp + acquire(&ptable.lock); +8010391c: 68 40 1d 11 80 push $0x80111d40 +80103921: e8 da 0d 00 00 call 80104700 +80103926: 83 c4 10 add $0x10,%esp + while (p < &ptable.proc[NPROC] && !found) { + if (p->state == UNUSED) { +80103929: 8b 43 0c mov 0xc(%ebx),%eax +8010392c: 85 c0 test %eax,%eax +8010392e: 74 28 je 80103958 + found = 1; + } + else { + p++; +80103930: 83 c3 7c add $0x7c,%ebx + while (p < &ptable.proc[NPROC] && !found) { +80103933: 81 fb 74 3c 11 80 cmp $0x80113c74,%ebx +80103939: 75 ee jne 80103929 + } + + } + if (!found) { + release(&ptable.lock); +8010393b: 83 ec 0c sub $0xc,%esp + return 0; +8010393e: 31 db xor %ebx,%ebx + release(&ptable.lock); +80103940: 68 40 1d 11 80 push $0x80111d40 +80103945: e8 56 0d 00 00 call 801046a0 + p->context = (struct context*)sp; + memset(p->context, 0, sizeof *p->context); + p->context->eip = (uint)forkret; + + return p; +} +8010394a: 89 d8 mov %ebx,%eax + return 0; +8010394c: 83 c4 10 add $0x10,%esp +} +8010394f: 8b 5d fc mov -0x4(%ebp),%ebx +80103952: c9 leave +80103953: c3 ret +80103954: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + p->pid = nextpid++; +80103958: a1 04 a0 10 80 mov 0x8010a004,%eax + release(&ptable.lock); +8010395d: 83 ec 0c sub $0xc,%esp + p->state = EMBRYO; +80103960: c7 43 0c 01 00 00 00 movl $0x1,0xc(%ebx) + p->pid = nextpid++; +80103967: 89 43 10 mov %eax,0x10(%ebx) +8010396a: 8d 50 01 lea 0x1(%eax),%edx + release(&ptable.lock); +8010396d: 68 40 1d 11 80 push $0x80111d40 + p->pid = nextpid++; +80103972: 89 15 04 a0 10 80 mov %edx,0x8010a004 + release(&ptable.lock); +80103978: e8 23 0d 00 00 call 801046a0 + if ((p->kstack = kalloc()) == 0) { +8010397d: e8 1e ee ff ff call 801027a0 +80103982: 83 c4 10 add $0x10,%esp +80103985: 89 43 08 mov %eax,0x8(%ebx) +80103988: 85 c0 test %eax,%eax +8010398a: 74 3c je 801039c8 + sp -= sizeof *p->tf; +8010398c: 8d 90 b4 0f 00 00 lea 0xfb4(%eax),%edx + memset(p->context, 0, sizeof *p->context); +80103992: 83 ec 04 sub $0x4,%esp + sp -= sizeof *p->context; +80103995: 05 9c 0f 00 00 add $0xf9c,%eax + sp -= sizeof *p->tf; +8010399a: 89 53 18 mov %edx,0x18(%ebx) + *(uint*)sp = (uint)trapret; +8010399d: c7 40 14 66 5a 10 80 movl $0x80105a66,0x14(%eax) + p->context = (struct context*)sp; +801039a4: 89 43 1c mov %eax,0x1c(%ebx) + memset(p->context, 0, sizeof *p->context); +801039a7: 6a 14 push $0x14 +801039a9: 6a 00 push $0x0 +801039ab: 50 push %eax +801039ac: e8 0f 0e 00 00 call 801047c0 + p->context->eip = (uint)forkret; +801039b1: 8b 43 1c mov 0x1c(%ebx),%eax + return p; +801039b4: 83 c4 10 add $0x10,%esp + p->context->eip = (uint)forkret; +801039b7: c7 40 10 e0 39 10 80 movl $0x801039e0,0x10(%eax) +} +801039be: 89 d8 mov %ebx,%eax +801039c0: 8b 5d fc mov -0x4(%ebp),%ebx +801039c3: c9 leave +801039c4: c3 ret +801039c5: 8d 76 00 lea 0x0(%esi),%esi + p->state = UNUSED; +801039c8: c7 43 0c 00 00 00 00 movl $0x0,0xc(%ebx) + return 0; +801039cf: 31 db xor %ebx,%ebx +} +801039d1: 89 d8 mov %ebx,%eax +801039d3: 8b 5d fc mov -0x4(%ebp),%ebx +801039d6: c9 leave +801039d7: c3 ret +801039d8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801039df: 90 nop + +801039e0 : + release(&ptable.lock); +} + +// A fork child's very first scheduling by scheduler() +// will swtch here. "Return" to user space. +void forkret(void) { +801039e0: 55 push %ebp +801039e1: 89 e5 mov %esp,%ebp +801039e3: 83 ec 14 sub $0x14,%esp + static int first = 1; + // Still holding ptable.lock from scheduler. + release(&ptable.lock); +801039e6: 68 40 1d 11 80 push $0x80111d40 +801039eb: e8 b0 0c 00 00 call 801046a0 + + if (first) { +801039f0: a1 00 a0 10 80 mov 0x8010a000,%eax +801039f5: 83 c4 10 add $0x10,%esp +801039f8: 85 c0 test %eax,%eax +801039fa: 75 04 jne 80103a00 + iinit(ROOTDEV); + initlog(ROOTDEV); + } + + // Return to "caller", actually trapret (see allocproc). +} +801039fc: c9 leave +801039fd: c3 ret +801039fe: 66 90 xchg %ax,%ax + first = 0; +80103a00: c7 05 00 a0 10 80 00 movl $0x0,0x8010a000 +80103a07: 00 00 00 + iinit(ROOTDEV); +80103a0a: 83 ec 0c sub $0xc,%esp +80103a0d: 6a 01 push $0x1 +80103a0f: e8 6c dc ff ff call 80101680 + initlog(ROOTDEV); +80103a14: c7 04 24 01 00 00 00 movl $0x1,(%esp) +80103a1b: e8 c0 f3 ff ff call 80102de0 +} +80103a20: 83 c4 10 add $0x10,%esp +80103a23: c9 leave +80103a24: c3 ret +80103a25: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103a2c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80103a30 : +void pinit(void) { +80103a30: 55 push %ebp +80103a31: 89 e5 mov %esp,%ebp +80103a33: 83 ec 10 sub $0x10,%esp + initlock(&ptable.lock, "ptable"); +80103a36: 68 20 79 10 80 push $0x80107920 +80103a3b: 68 40 1d 11 80 push $0x80111d40 +80103a40: e8 eb 0a 00 00 call 80104530 +} +80103a45: 83 c4 10 add $0x10,%esp +80103a48: c9 leave +80103a49: c3 ret +80103a4a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80103a50 : +struct cpu*mycpu(void) { +80103a50: 55 push %ebp +80103a51: 89 e5 mov %esp,%ebp +80103a53: 56 push %esi +80103a54: 53 push %ebx + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +80103a55: 9c pushf +80103a56: 58 pop %eax + if (readeflags() & FL_IF) { +80103a57: f6 c4 02 test $0x2,%ah +80103a5a: 75 46 jne 80103aa2 + apicid = lapicid(); +80103a5c: e8 af ef ff ff call 80102a10 + for (i = 0; i < ncpu; ++i) { +80103a61: 8b 35 a4 17 11 80 mov 0x801117a4,%esi +80103a67: 85 f6 test %esi,%esi +80103a69: 7e 2a jle 80103a95 +80103a6b: 31 d2 xor %edx,%edx +80103a6d: eb 08 jmp 80103a77 +80103a6f: 90 nop +80103a70: 83 c2 01 add $0x1,%edx +80103a73: 39 f2 cmp %esi,%edx +80103a75: 74 1e je 80103a95 + if (cpus[i].apicid == apicid) { +80103a77: 69 ca b0 00 00 00 imul $0xb0,%edx,%ecx +80103a7d: 0f b6 99 c0 17 11 80 movzbl -0x7feee840(%ecx),%ebx +80103a84: 39 c3 cmp %eax,%ebx +80103a86: 75 e8 jne 80103a70 +} +80103a88: 8d 65 f8 lea -0x8(%ebp),%esp + return &cpus[i]; +80103a8b: 8d 81 c0 17 11 80 lea -0x7feee840(%ecx),%eax +} +80103a91: 5b pop %ebx +80103a92: 5e pop %esi +80103a93: 5d pop %ebp +80103a94: c3 ret + panic("unknown apicid\n"); +80103a95: 83 ec 0c sub $0xc,%esp +80103a98: 68 27 79 10 80 push $0x80107927 +80103a9d: e8 ee c8 ff ff call 80100390 + panic("mycpu called with interrupts enabled\n"); +80103aa2: 83 ec 0c sub $0xc,%esp +80103aa5: 68 04 7a 10 80 push $0x80107a04 +80103aaa: e8 e1 c8 ff ff call 80100390 +80103aaf: 90 nop + +80103ab0 : +int cpuid() { +80103ab0: 55 push %ebp +80103ab1: 89 e5 mov %esp,%ebp +80103ab3: 83 ec 08 sub $0x8,%esp + return mycpu() - cpus; +80103ab6: e8 95 ff ff ff call 80103a50 +} +80103abb: c9 leave + return mycpu() - cpus; +80103abc: 2d c0 17 11 80 sub $0x801117c0,%eax +80103ac1: c1 f8 04 sar $0x4,%eax +80103ac4: 69 c0 a3 8b 2e ba imul $0xba2e8ba3,%eax,%eax +} +80103aca: c3 ret +80103acb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80103acf: 90 nop + +80103ad0 : +struct proc*myproc(void) { +80103ad0: 55 push %ebp +80103ad1: 89 e5 mov %esp,%ebp +80103ad3: 53 push %ebx +80103ad4: 83 ec 04 sub $0x4,%esp + pushcli(); +80103ad7: e8 d4 0a 00 00 call 801045b0 + c = mycpu(); +80103adc: e8 6f ff ff ff call 80103a50 + p = c->proc; +80103ae1: 8b 98 ac 00 00 00 mov 0xac(%eax),%ebx + popcli(); +80103ae7: e8 14 0b 00 00 call 80104600 +} +80103aec: 89 d8 mov %ebx,%eax +80103aee: 8b 5d fc mov -0x4(%ebp),%ebx +80103af1: c9 leave +80103af2: c3 ret +80103af3: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103afa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80103b00 : +void userinit(void) { +80103b00: 55 push %ebp +80103b01: 89 e5 mov %esp,%ebp +80103b03: 53 push %ebx +80103b04: 83 ec 04 sub $0x4,%esp + p = allocproc(); +80103b07: e8 04 fe ff ff call 80103910 +80103b0c: 89 c3 mov %eax,%ebx + initproc = p; +80103b0e: a3 74 3c 11 80 mov %eax,0x80113c74 + if ((p->pgdir = setupkvm()) == 0) { +80103b13: e8 48 35 00 00 call 80107060 +80103b18: 89 43 04 mov %eax,0x4(%ebx) +80103b1b: 85 c0 test %eax,%eax +80103b1d: 0f 84 bd 00 00 00 je 80103be0 + inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size); +80103b23: 83 ec 04 sub $0x4,%esp +80103b26: 68 2c 00 00 00 push $0x2c +80103b2b: 68 60 a4 10 80 push $0x8010a460 +80103b30: 50 push %eax +80103b31: e8 da 31 00 00 call 80106d10 + memset(p->tf, 0, sizeof(*p->tf)); +80103b36: 83 c4 0c add $0xc,%esp + p->sz = PGSIZE; +80103b39: c7 03 00 10 00 00 movl $0x1000,(%ebx) + memset(p->tf, 0, sizeof(*p->tf)); +80103b3f: 6a 4c push $0x4c +80103b41: 6a 00 push $0x0 +80103b43: ff 73 18 push 0x18(%ebx) +80103b46: e8 75 0c 00 00 call 801047c0 + p->tf->cs = (SEG_UCODE << 3) | DPL_USER; +80103b4b: 8b 43 18 mov 0x18(%ebx),%eax +80103b4e: ba 1b 00 00 00 mov $0x1b,%edx + safestrcpy(p->name, "initcode", sizeof(p->name)); +80103b53: 83 c4 0c add $0xc,%esp + p->tf->ds = (SEG_UDATA << 3) | DPL_USER; +80103b56: b9 23 00 00 00 mov $0x23,%ecx + p->tf->cs = (SEG_UCODE << 3) | DPL_USER; +80103b5b: 66 89 50 3c mov %dx,0x3c(%eax) + p->tf->ds = (SEG_UDATA << 3) | DPL_USER; +80103b5f: 8b 43 18 mov 0x18(%ebx),%eax +80103b62: 66 89 48 2c mov %cx,0x2c(%eax) + p->tf->es = p->tf->ds; +80103b66: 8b 43 18 mov 0x18(%ebx),%eax +80103b69: 0f b7 50 2c movzwl 0x2c(%eax),%edx +80103b6d: 66 89 50 28 mov %dx,0x28(%eax) + p->tf->ss = p->tf->ds; +80103b71: 8b 43 18 mov 0x18(%ebx),%eax +80103b74: 0f b7 50 2c movzwl 0x2c(%eax),%edx +80103b78: 66 89 50 48 mov %dx,0x48(%eax) + p->tf->eflags = FL_IF; +80103b7c: 8b 43 18 mov 0x18(%ebx),%eax +80103b7f: c7 40 40 00 02 00 00 movl $0x200,0x40(%eax) + p->tf->esp = PGSIZE; +80103b86: 8b 43 18 mov 0x18(%ebx),%eax +80103b89: c7 40 44 00 10 00 00 movl $0x1000,0x44(%eax) + p->tf->eip = 0; // beginning of initcode.S +80103b90: 8b 43 18 mov 0x18(%ebx),%eax +80103b93: c7 40 38 00 00 00 00 movl $0x0,0x38(%eax) + safestrcpy(p->name, "initcode", sizeof(p->name)); +80103b9a: 8d 43 6c lea 0x6c(%ebx),%eax +80103b9d: 6a 10 push $0x10 +80103b9f: 68 50 79 10 80 push $0x80107950 +80103ba4: 50 push %eax +80103ba5: e8 d6 0d 00 00 call 80104980 + p->cwd = namei("/"); +80103baa: c7 04 24 59 79 10 80 movl $0x80107959,(%esp) +80103bb1: e8 0a e6 ff ff call 801021c0 +80103bb6: 89 43 68 mov %eax,0x68(%ebx) + acquire(&ptable.lock); +80103bb9: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +80103bc0: e8 3b 0b 00 00 call 80104700 + p->state = RUNNABLE; +80103bc5: c7 43 0c 03 00 00 00 movl $0x3,0xc(%ebx) + release(&ptable.lock); +80103bcc: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +80103bd3: e8 c8 0a 00 00 call 801046a0 +} +80103bd8: 8b 5d fc mov -0x4(%ebp),%ebx +80103bdb: 83 c4 10 add $0x10,%esp +80103bde: c9 leave +80103bdf: c3 ret + panic("userinit: out of memory?"); +80103be0: 83 ec 0c sub $0xc,%esp +80103be3: 68 37 79 10 80 push $0x80107937 +80103be8: e8 a3 c7 ff ff call 80100390 +80103bed: 8d 76 00 lea 0x0(%esi),%esi + +80103bf0 : +int growproc(int n) { +80103bf0: 55 push %ebp +80103bf1: 89 e5 mov %esp,%ebp +80103bf3: 56 push %esi +80103bf4: 53 push %ebx +80103bf5: 8b 75 08 mov 0x8(%ebp),%esi + pushcli(); +80103bf8: e8 b3 09 00 00 call 801045b0 + c = mycpu(); +80103bfd: e8 4e fe ff ff call 80103a50 + p = c->proc; +80103c02: 8b 98 ac 00 00 00 mov 0xac(%eax),%ebx + popcli(); +80103c08: e8 f3 09 00 00 call 80104600 + sz = curproc->sz; +80103c0d: 8b 03 mov (%ebx),%eax + if (n > 0) { +80103c0f: 85 f6 test %esi,%esi +80103c11: 7f 1d jg 80103c30 + else if (n < 0) { +80103c13: 75 3b jne 80103c50 + switchuvm(curproc); +80103c15: 83 ec 0c sub $0xc,%esp + curproc->sz = sz; +80103c18: 89 03 mov %eax,(%ebx) + switchuvm(curproc); +80103c1a: 53 push %ebx +80103c1b: e8 e0 2f 00 00 call 80106c00 + return 0; +80103c20: 83 c4 10 add $0x10,%esp +80103c23: 31 c0 xor %eax,%eax +} +80103c25: 8d 65 f8 lea -0x8(%ebp),%esp +80103c28: 5b pop %ebx +80103c29: 5e pop %esi +80103c2a: 5d pop %ebp +80103c2b: c3 ret +80103c2c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if ((sz = allocuvm(curproc->pgdir, sz, sz + n)) == 0) { +80103c30: 83 ec 04 sub $0x4,%esp +80103c33: 01 c6 add %eax,%esi +80103c35: 56 push %esi +80103c36: 50 push %eax +80103c37: ff 73 04 push 0x4(%ebx) +80103c3a: e8 41 32 00 00 call 80106e80 +80103c3f: 83 c4 10 add $0x10,%esp +80103c42: 85 c0 test %eax,%eax +80103c44: 75 cf jne 80103c15 + return -1; +80103c46: b8 ff ff ff ff mov $0xffffffff,%eax +80103c4b: eb d8 jmp 80103c25 +80103c4d: 8d 76 00 lea 0x0(%esi),%esi + if ((sz = deallocuvm(curproc->pgdir, sz, sz + n)) == 0) { +80103c50: 83 ec 04 sub $0x4,%esp +80103c53: 01 c6 add %eax,%esi +80103c55: 56 push %esi +80103c56: 50 push %eax +80103c57: ff 73 04 push 0x4(%ebx) +80103c5a: e8 51 33 00 00 call 80106fb0 +80103c5f: 83 c4 10 add $0x10,%esp +80103c62: 85 c0 test %eax,%eax +80103c64: 75 af jne 80103c15 +80103c66: eb de jmp 80103c46 +80103c68: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103c6f: 90 nop + +80103c70 : +int fork(void) { +80103c70: 55 push %ebp +80103c71: 89 e5 mov %esp,%ebp +80103c73: 57 push %edi +80103c74: 56 push %esi +80103c75: 53 push %ebx +80103c76: 83 ec 1c sub $0x1c,%esp + pushcli(); +80103c79: e8 32 09 00 00 call 801045b0 + c = mycpu(); +80103c7e: e8 cd fd ff ff call 80103a50 + p = c->proc; +80103c83: 8b 98 ac 00 00 00 mov 0xac(%eax),%ebx + popcli(); +80103c89: e8 72 09 00 00 call 80104600 + if ((np = allocproc()) == 0) { +80103c8e: e8 7d fc ff ff call 80103910 +80103c93: 89 45 e4 mov %eax,-0x1c(%ebp) +80103c96: 85 c0 test %eax,%eax +80103c98: 0f 84 b7 00 00 00 je 80103d55 + if ((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0) { +80103c9e: 83 ec 08 sub $0x8,%esp +80103ca1: ff 33 push (%ebx) +80103ca3: 89 c7 mov %eax,%edi +80103ca5: ff 73 04 push 0x4(%ebx) +80103ca8: e8 a3 34 00 00 call 80107150 +80103cad: 83 c4 10 add $0x10,%esp +80103cb0: 89 47 04 mov %eax,0x4(%edi) +80103cb3: 85 c0 test %eax,%eax +80103cb5: 0f 84 a1 00 00 00 je 80103d5c + np->sz = curproc->sz; +80103cbb: 8b 03 mov (%ebx),%eax +80103cbd: 8b 4d e4 mov -0x1c(%ebp),%ecx +80103cc0: 89 01 mov %eax,(%ecx) + *np->tf = *curproc->tf; +80103cc2: 8b 79 18 mov 0x18(%ecx),%edi + np->parent = curproc; +80103cc5: 89 c8 mov %ecx,%eax +80103cc7: 89 59 14 mov %ebx,0x14(%ecx) + *np->tf = *curproc->tf; +80103cca: b9 13 00 00 00 mov $0x13,%ecx +80103ccf: 8b 73 18 mov 0x18(%ebx),%esi +80103cd2: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + for (i = 0; i < NOFILE; i++) { +80103cd4: 31 f6 xor %esi,%esi + np->tf->eax = 0; +80103cd6: 8b 40 18 mov 0x18(%eax),%eax +80103cd9: c7 40 1c 00 00 00 00 movl $0x0,0x1c(%eax) + if (curproc->ofile[i]) { +80103ce0: 8b 44 b3 28 mov 0x28(%ebx,%esi,4),%eax +80103ce4: 85 c0 test %eax,%eax +80103ce6: 74 13 je 80103cfb + np->ofile[i] = filedup(curproc->ofile[i]); +80103ce8: 83 ec 0c sub $0xc,%esp +80103ceb: 50 push %eax +80103cec: e8 cf d2 ff ff call 80100fc0 +80103cf1: 8b 55 e4 mov -0x1c(%ebp),%edx +80103cf4: 83 c4 10 add $0x10,%esp +80103cf7: 89 44 b2 28 mov %eax,0x28(%edx,%esi,4) + for (i = 0; i < NOFILE; i++) { +80103cfb: 83 c6 01 add $0x1,%esi +80103cfe: 83 fe 10 cmp $0x10,%esi +80103d01: 75 dd jne 80103ce0 + np->cwd = idup(curproc->cwd); +80103d03: 83 ec 0c sub $0xc,%esp +80103d06: ff 73 68 push 0x68(%ebx) + safestrcpy(np->name, curproc->name, sizeof(curproc->name)); +80103d09: 83 c3 6c add $0x6c,%ebx + np->cwd = idup(curproc->cwd); +80103d0c: e8 5f db ff ff call 80101870 +80103d11: 8b 7d e4 mov -0x1c(%ebp),%edi + safestrcpy(np->name, curproc->name, sizeof(curproc->name)); +80103d14: 83 c4 0c add $0xc,%esp + np->cwd = idup(curproc->cwd); +80103d17: 89 47 68 mov %eax,0x68(%edi) + safestrcpy(np->name, curproc->name, sizeof(curproc->name)); +80103d1a: 8d 47 6c lea 0x6c(%edi),%eax +80103d1d: 6a 10 push $0x10 +80103d1f: 53 push %ebx +80103d20: 50 push %eax +80103d21: e8 5a 0c 00 00 call 80104980 + pid = np->pid; +80103d26: 8b 5f 10 mov 0x10(%edi),%ebx + acquire(&ptable.lock); +80103d29: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +80103d30: e8 cb 09 00 00 call 80104700 + np->state = RUNNABLE; +80103d35: c7 47 0c 03 00 00 00 movl $0x3,0xc(%edi) + release(&ptable.lock); +80103d3c: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +80103d43: e8 58 09 00 00 call 801046a0 + return pid; +80103d48: 83 c4 10 add $0x10,%esp +} +80103d4b: 8d 65 f4 lea -0xc(%ebp),%esp +80103d4e: 89 d8 mov %ebx,%eax +80103d50: 5b pop %ebx +80103d51: 5e pop %esi +80103d52: 5f pop %edi +80103d53: 5d pop %ebp +80103d54: c3 ret + return -1; +80103d55: bb ff ff ff ff mov $0xffffffff,%ebx +80103d5a: eb ef jmp 80103d4b + kfree(np->kstack); +80103d5c: 8b 5d e4 mov -0x1c(%ebp),%ebx +80103d5f: 83 ec 0c sub $0xc,%esp +80103d62: ff 73 08 push 0x8(%ebx) +80103d65: e8 76 e8 ff ff call 801025e0 + np->kstack = 0; +80103d6a: c7 43 08 00 00 00 00 movl $0x0,0x8(%ebx) + return -1; +80103d71: 83 c4 10 add $0x10,%esp + np->state = UNUSED; +80103d74: c7 43 0c 00 00 00 00 movl $0x0,0xc(%ebx) + return -1; +80103d7b: bb ff ff ff ff mov $0xffffffff,%ebx +80103d80: eb c9 jmp 80103d4b +80103d82: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103d89: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80103d90 : +void scheduler(void) { +80103d90: 55 push %ebp +80103d91: 89 e5 mov %esp,%ebp +80103d93: 57 push %edi +80103d94: 56 push %esi +80103d95: 53 push %ebx +80103d96: 83 ec 0c sub $0xc,%esp + struct cpu *c = mycpu(); +80103d99: e8 b2 fc ff ff call 80103a50 + c->proc = 0; +80103d9e: c7 80 ac 00 00 00 00 movl $0x0,0xac(%eax) +80103da5: 00 00 00 + struct cpu *c = mycpu(); +80103da8: 89 c6 mov %eax,%esi + c->proc = 0; +80103daa: 8d 78 04 lea 0x4(%eax),%edi +80103dad: 8d 76 00 lea 0x0(%esi),%esi + asm volatile ("sti"); +80103db0: fb sti + acquire(&ptable.lock); +80103db1: 83 ec 0c sub $0xc,%esp + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80103db4: bb 74 1d 11 80 mov $0x80111d74,%ebx + acquire(&ptable.lock); +80103db9: 68 40 1d 11 80 push $0x80111d40 +80103dbe: e8 3d 09 00 00 call 80104700 +80103dc3: 83 c4 10 add $0x10,%esp +80103dc6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103dcd: 8d 76 00 lea 0x0(%esi),%esi + if (p->state != RUNNABLE) { +80103dd0: 83 7b 0c 03 cmpl $0x3,0xc(%ebx) +80103dd4: 75 33 jne 80103e09 + switchuvm(p); +80103dd6: 83 ec 0c sub $0xc,%esp + c->proc = p; +80103dd9: 89 9e ac 00 00 00 mov %ebx,0xac(%esi) + switchuvm(p); +80103ddf: 53 push %ebx +80103de0: e8 1b 2e 00 00 call 80106c00 + swtch(&(c->scheduler), p->context); +80103de5: 58 pop %eax +80103de6: 5a pop %edx +80103de7: ff 73 1c push 0x1c(%ebx) +80103dea: 57 push %edi + p->state = RUNNING; +80103deb: c7 43 0c 04 00 00 00 movl $0x4,0xc(%ebx) + swtch(&(c->scheduler), p->context); +80103df2: e8 e4 0b 00 00 call 801049db + switchkvm(); +80103df7: e8 f4 2d 00 00 call 80106bf0 + c->proc = 0; +80103dfc: 83 c4 10 add $0x10,%esp +80103dff: c7 86 ac 00 00 00 00 movl $0x0,0xac(%esi) +80103e06: 00 00 00 + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80103e09: 83 c3 7c add $0x7c,%ebx +80103e0c: 81 fb 74 3c 11 80 cmp $0x80113c74,%ebx +80103e12: 75 bc jne 80103dd0 + release(&ptable.lock); +80103e14: 83 ec 0c sub $0xc,%esp +80103e17: 68 40 1d 11 80 push $0x80111d40 +80103e1c: e8 7f 08 00 00 call 801046a0 + sti(); +80103e21: 83 c4 10 add $0x10,%esp +80103e24: eb 8a jmp 80103db0 +80103e26: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103e2d: 8d 76 00 lea 0x0(%esi),%esi + +80103e30 : +void sched(void) { +80103e30: 55 push %ebp +80103e31: 89 e5 mov %esp,%ebp +80103e33: 56 push %esi +80103e34: 53 push %ebx + pushcli(); +80103e35: e8 76 07 00 00 call 801045b0 + c = mycpu(); +80103e3a: e8 11 fc ff ff call 80103a50 + p = c->proc; +80103e3f: 8b 98 ac 00 00 00 mov 0xac(%eax),%ebx + popcli(); +80103e45: e8 b6 07 00 00 call 80104600 + if (!holding(&ptable.lock)) { +80103e4a: 83 ec 0c sub $0xc,%esp +80103e4d: 68 40 1d 11 80 push $0x80111d40 +80103e52: e8 09 08 00 00 call 80104660 +80103e57: 83 c4 10 add $0x10,%esp +80103e5a: 85 c0 test %eax,%eax +80103e5c: 74 4f je 80103ead + if (mycpu()->ncli != 1) { +80103e5e: e8 ed fb ff ff call 80103a50 +80103e63: 83 b8 a4 00 00 00 01 cmpl $0x1,0xa4(%eax) +80103e6a: 75 68 jne 80103ed4 + if (p->state == RUNNING) { +80103e6c: 83 7b 0c 04 cmpl $0x4,0xc(%ebx) +80103e70: 74 55 je 80103ec7 + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +80103e72: 9c pushf +80103e73: 58 pop %eax + if (readeflags() & FL_IF) { +80103e74: f6 c4 02 test $0x2,%ah +80103e77: 75 41 jne 80103eba + intena = mycpu()->intena; +80103e79: e8 d2 fb ff ff call 80103a50 + swtch(&p->context, mycpu()->scheduler); +80103e7e: 83 c3 1c add $0x1c,%ebx + intena = mycpu()->intena; +80103e81: 8b b0 a8 00 00 00 mov 0xa8(%eax),%esi + swtch(&p->context, mycpu()->scheduler); +80103e87: e8 c4 fb ff ff call 80103a50 +80103e8c: 83 ec 08 sub $0x8,%esp +80103e8f: ff 70 04 push 0x4(%eax) +80103e92: 53 push %ebx +80103e93: e8 43 0b 00 00 call 801049db + mycpu()->intena = intena; +80103e98: e8 b3 fb ff ff call 80103a50 +} +80103e9d: 83 c4 10 add $0x10,%esp + mycpu()->intena = intena; +80103ea0: 89 b0 a8 00 00 00 mov %esi,0xa8(%eax) +} +80103ea6: 8d 65 f8 lea -0x8(%ebp),%esp +80103ea9: 5b pop %ebx +80103eaa: 5e pop %esi +80103eab: 5d pop %ebp +80103eac: c3 ret + panic("sched ptable.lock"); +80103ead: 83 ec 0c sub $0xc,%esp +80103eb0: 68 5b 79 10 80 push $0x8010795b +80103eb5: e8 d6 c4 ff ff call 80100390 + panic("sched interruptible"); +80103eba: 83 ec 0c sub $0xc,%esp +80103ebd: 68 87 79 10 80 push $0x80107987 +80103ec2: e8 c9 c4 ff ff call 80100390 + panic("sched running"); +80103ec7: 83 ec 0c sub $0xc,%esp +80103eca: 68 79 79 10 80 push $0x80107979 +80103ecf: e8 bc c4 ff ff call 80100390 + panic("sched locks"); +80103ed4: 83 ec 0c sub $0xc,%esp +80103ed7: 68 6d 79 10 80 push $0x8010796d +80103edc: e8 af c4 ff ff call 80100390 +80103ee1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103ee8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103eef: 90 nop + +80103ef0 : +void exit(void) { +80103ef0: 55 push %ebp +80103ef1: 89 e5 mov %esp,%ebp +80103ef3: 57 push %edi +80103ef4: 56 push %esi +80103ef5: 53 push %ebx +80103ef6: 83 ec 0c sub $0xc,%esp + struct proc *curproc = myproc(); +80103ef9: e8 d2 fb ff ff call 80103ad0 + if (curproc == initproc) { +80103efe: 39 05 74 3c 11 80 cmp %eax,0x80113c74 +80103f04: 0f 84 fd 00 00 00 je 80104007 +80103f0a: 89 c3 mov %eax,%ebx +80103f0c: 8d 70 28 lea 0x28(%eax),%esi +80103f0f: 8d 78 68 lea 0x68(%eax),%edi +80103f12: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (curproc->ofile[fd]) { +80103f18: 8b 06 mov (%esi),%eax +80103f1a: 85 c0 test %eax,%eax +80103f1c: 74 12 je 80103f30 + fileclose(curproc->ofile[fd]); +80103f1e: 83 ec 0c sub $0xc,%esp +80103f21: 50 push %eax +80103f22: e8 e9 d0 ff ff call 80101010 + curproc->ofile[fd] = 0; +80103f27: c7 06 00 00 00 00 movl $0x0,(%esi) +80103f2d: 83 c4 10 add $0x10,%esp + for (fd = 0; fd < NOFILE; fd++) { +80103f30: 83 c6 04 add $0x4,%esi +80103f33: 39 f7 cmp %esi,%edi +80103f35: 75 e1 jne 80103f18 + begin_op(); +80103f37: e8 44 ef ff ff call 80102e80 + iput(curproc->cwd); +80103f3c: 83 ec 0c sub $0xc,%esp +80103f3f: ff 73 68 push 0x68(%ebx) +80103f42: e8 89 da ff ff call 801019d0 + end_op(); +80103f47: e8 a4 ef ff ff call 80102ef0 + curproc->cwd = 0; +80103f4c: c7 43 68 00 00 00 00 movl $0x0,0x68(%ebx) + acquire(&ptable.lock); +80103f53: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +80103f5a: e8 a1 07 00 00 call 80104700 + wakeup1(curproc->parent); +80103f5f: 8b 53 14 mov 0x14(%ebx),%edx +80103f62: 83 c4 10 add $0x10,%esp +// Wake up all processes sleeping on chan. +// The ptable lock must be held. +static void wakeup1(void *chan) { + struct proc *p; + + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80103f65: b8 74 1d 11 80 mov $0x80111d74,%eax +80103f6a: eb 0e jmp 80103f7a +80103f6c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80103f70: 83 c0 7c add $0x7c,%eax +80103f73: 3d 74 3c 11 80 cmp $0x80113c74,%eax +80103f78: 74 1c je 80103f96 + if (p->state == SLEEPING && p->chan == chan) { +80103f7a: 83 78 0c 02 cmpl $0x2,0xc(%eax) +80103f7e: 75 f0 jne 80103f70 +80103f80: 3b 50 20 cmp 0x20(%eax),%edx +80103f83: 75 eb jne 80103f70 + p->state = RUNNABLE; +80103f85: c7 40 0c 03 00 00 00 movl $0x3,0xc(%eax) + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80103f8c: 83 c0 7c add $0x7c,%eax +80103f8f: 3d 74 3c 11 80 cmp $0x80113c74,%eax +80103f94: 75 e4 jne 80103f7a + p->parent = initproc; +80103f96: 8b 0d 74 3c 11 80 mov 0x80113c74,%ecx + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80103f9c: ba 74 1d 11 80 mov $0x80111d74,%edx +80103fa1: eb 10 jmp 80103fb3 +80103fa3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80103fa7: 90 nop +80103fa8: 83 c2 7c add $0x7c,%edx +80103fab: 81 fa 74 3c 11 80 cmp $0x80113c74,%edx +80103fb1: 74 3b je 80103fee + if (p->parent == curproc) { +80103fb3: 39 5a 14 cmp %ebx,0x14(%edx) +80103fb6: 75 f0 jne 80103fa8 + if (p->state == ZOMBIE) { +80103fb8: 83 7a 0c 05 cmpl $0x5,0xc(%edx) + p->parent = initproc; +80103fbc: 89 4a 14 mov %ecx,0x14(%edx) + if (p->state == ZOMBIE) { +80103fbf: 75 e7 jne 80103fa8 + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80103fc1: b8 74 1d 11 80 mov $0x80111d74,%eax +80103fc6: eb 12 jmp 80103fda +80103fc8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80103fcf: 90 nop +80103fd0: 83 c0 7c add $0x7c,%eax +80103fd3: 3d 74 3c 11 80 cmp $0x80113c74,%eax +80103fd8: 74 ce je 80103fa8 + if (p->state == SLEEPING && p->chan == chan) { +80103fda: 83 78 0c 02 cmpl $0x2,0xc(%eax) +80103fde: 75 f0 jne 80103fd0 +80103fe0: 3b 48 20 cmp 0x20(%eax),%ecx +80103fe3: 75 eb jne 80103fd0 + p->state = RUNNABLE; +80103fe5: c7 40 0c 03 00 00 00 movl $0x3,0xc(%eax) +80103fec: eb e2 jmp 80103fd0 + curproc->state = ZOMBIE; +80103fee: c7 43 0c 05 00 00 00 movl $0x5,0xc(%ebx) + sched(); +80103ff5: e8 36 fe ff ff call 80103e30 + panic("zombie exit"); +80103ffa: 83 ec 0c sub $0xc,%esp +80103ffd: 68 a8 79 10 80 push $0x801079a8 +80104002: e8 89 c3 ff ff call 80100390 + panic("init exiting"); +80104007: 83 ec 0c sub $0xc,%esp +8010400a: 68 9b 79 10 80 push $0x8010799b +8010400f: e8 7c c3 ff ff call 80100390 +80104014: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010401b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010401f: 90 nop + +80104020 : +int wait(void) { +80104020: 55 push %ebp +80104021: 89 e5 mov %esp,%ebp +80104023: 56 push %esi +80104024: 53 push %ebx + pushcli(); +80104025: e8 86 05 00 00 call 801045b0 + c = mycpu(); +8010402a: e8 21 fa ff ff call 80103a50 + p = c->proc; +8010402f: 8b b0 ac 00 00 00 mov 0xac(%eax),%esi + popcli(); +80104035: e8 c6 05 00 00 call 80104600 + acquire(&ptable.lock); +8010403a: 83 ec 0c sub $0xc,%esp +8010403d: 68 40 1d 11 80 push $0x80111d40 +80104042: e8 b9 06 00 00 call 80104700 +80104047: 83 c4 10 add $0x10,%esp + havekids = 0; +8010404a: 31 c0 xor %eax,%eax + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +8010404c: bb 74 1d 11 80 mov $0x80111d74,%ebx +80104051: eb 10 jmp 80104063 +80104053: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104057: 90 nop +80104058: 83 c3 7c add $0x7c,%ebx +8010405b: 81 fb 74 3c 11 80 cmp $0x80113c74,%ebx +80104061: 74 1b je 8010407e + if (p->parent != curproc) { +80104063: 39 73 14 cmp %esi,0x14(%ebx) +80104066: 75 f0 jne 80104058 + if (p->state == ZOMBIE) { +80104068: 83 7b 0c 05 cmpl $0x5,0xc(%ebx) +8010406c: 74 62 je 801040d0 + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +8010406e: 83 c3 7c add $0x7c,%ebx + havekids = 1; +80104071: b8 01 00 00 00 mov $0x1,%eax + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80104076: 81 fb 74 3c 11 80 cmp $0x80113c74,%ebx +8010407c: 75 e5 jne 80104063 + if (!havekids || curproc->killed) { +8010407e: 85 c0 test %eax,%eax +80104080: 0f 84 a0 00 00 00 je 80104126 +80104086: 8b 46 24 mov 0x24(%esi),%eax +80104089: 85 c0 test %eax,%eax +8010408b: 0f 85 95 00 00 00 jne 80104126 + pushcli(); +80104091: e8 1a 05 00 00 call 801045b0 + c = mycpu(); +80104096: e8 b5 f9 ff ff call 80103a50 + p = c->proc; +8010409b: 8b 98 ac 00 00 00 mov 0xac(%eax),%ebx + popcli(); +801040a1: e8 5a 05 00 00 call 80104600 + if (p == 0) { +801040a6: 85 db test %ebx,%ebx +801040a8: 0f 84 8f 00 00 00 je 8010413d + p->chan = chan; +801040ae: 89 73 20 mov %esi,0x20(%ebx) + p->state = SLEEPING; +801040b1: c7 43 0c 02 00 00 00 movl $0x2,0xc(%ebx) + sched(); +801040b8: e8 73 fd ff ff call 80103e30 + p->chan = 0; +801040bd: c7 43 20 00 00 00 00 movl $0x0,0x20(%ebx) +} +801040c4: eb 84 jmp 8010404a +801040c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801040cd: 8d 76 00 lea 0x0(%esi),%esi + kfree(p->kstack); +801040d0: 83 ec 0c sub $0xc,%esp + pid = p->pid; +801040d3: 8b 73 10 mov 0x10(%ebx),%esi + kfree(p->kstack); +801040d6: ff 73 08 push 0x8(%ebx) +801040d9: e8 02 e5 ff ff call 801025e0 + p->kstack = 0; +801040de: c7 43 08 00 00 00 00 movl $0x0,0x8(%ebx) + freevm(p->pgdir); +801040e5: 5a pop %edx +801040e6: ff 73 04 push 0x4(%ebx) +801040e9: e8 f2 2e 00 00 call 80106fe0 + p->pid = 0; +801040ee: c7 43 10 00 00 00 00 movl $0x0,0x10(%ebx) + p->parent = 0; +801040f5: c7 43 14 00 00 00 00 movl $0x0,0x14(%ebx) + p->name[0] = 0; +801040fc: c6 43 6c 00 movb $0x0,0x6c(%ebx) + p->killed = 0; +80104100: c7 43 24 00 00 00 00 movl $0x0,0x24(%ebx) + p->state = UNUSED; +80104107: c7 43 0c 00 00 00 00 movl $0x0,0xc(%ebx) + release(&ptable.lock); +8010410e: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +80104115: e8 86 05 00 00 call 801046a0 + return pid; +8010411a: 83 c4 10 add $0x10,%esp +} +8010411d: 8d 65 f8 lea -0x8(%ebp),%esp +80104120: 89 f0 mov %esi,%eax +80104122: 5b pop %ebx +80104123: 5e pop %esi +80104124: 5d pop %ebp +80104125: c3 ret + release(&ptable.lock); +80104126: 83 ec 0c sub $0xc,%esp + return -1; +80104129: be ff ff ff ff mov $0xffffffff,%esi + release(&ptable.lock); +8010412e: 68 40 1d 11 80 push $0x80111d40 +80104133: e8 68 05 00 00 call 801046a0 + return -1; +80104138: 83 c4 10 add $0x10,%esp +8010413b: eb e0 jmp 8010411d + panic("sleep"); +8010413d: 83 ec 0c sub $0xc,%esp +80104140: 68 b4 79 10 80 push $0x801079b4 +80104145: e8 46 c2 ff ff call 80100390 +8010414a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80104150 : +void yield(void) { +80104150: 55 push %ebp +80104151: 89 e5 mov %esp,%ebp +80104153: 53 push %ebx +80104154: 83 ec 10 sub $0x10,%esp + acquire(&ptable.lock); //DOC: yieldlock +80104157: 68 40 1d 11 80 push $0x80111d40 +8010415c: e8 9f 05 00 00 call 80104700 + pushcli(); +80104161: e8 4a 04 00 00 call 801045b0 + c = mycpu(); +80104166: e8 e5 f8 ff ff call 80103a50 + p = c->proc; +8010416b: 8b 98 ac 00 00 00 mov 0xac(%eax),%ebx + popcli(); +80104171: e8 8a 04 00 00 call 80104600 + myproc()->state = RUNNABLE; +80104176: c7 43 0c 03 00 00 00 movl $0x3,0xc(%ebx) + sched(); +8010417d: e8 ae fc ff ff call 80103e30 + release(&ptable.lock); +80104182: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +80104189: e8 12 05 00 00 call 801046a0 +} +8010418e: 8b 5d fc mov -0x4(%ebp),%ebx +80104191: 83 c4 10 add $0x10,%esp +80104194: c9 leave +80104195: c3 ret +80104196: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010419d: 8d 76 00 lea 0x0(%esi),%esi + +801041a0 : +void sleep(void *chan, struct spinlock *lk) { +801041a0: 55 push %ebp +801041a1: 89 e5 mov %esp,%ebp +801041a3: 57 push %edi +801041a4: 56 push %esi +801041a5: 53 push %ebx +801041a6: 83 ec 0c sub $0xc,%esp +801041a9: 8b 7d 08 mov 0x8(%ebp),%edi +801041ac: 8b 75 0c mov 0xc(%ebp),%esi + pushcli(); +801041af: e8 fc 03 00 00 call 801045b0 + c = mycpu(); +801041b4: e8 97 f8 ff ff call 80103a50 + p = c->proc; +801041b9: 8b 98 ac 00 00 00 mov 0xac(%eax),%ebx + popcli(); +801041bf: e8 3c 04 00 00 call 80104600 + if (p == 0) { +801041c4: 85 db test %ebx,%ebx +801041c6: 0f 84 87 00 00 00 je 80104253 + if (lk == 0) { +801041cc: 85 f6 test %esi,%esi +801041ce: 74 76 je 80104246 + if (lk != &ptable.lock) { //DOC: sleeplock0 +801041d0: 81 fe 40 1d 11 80 cmp $0x80111d40,%esi +801041d6: 74 50 je 80104228 + acquire(&ptable.lock); //DOC: sleeplock1 +801041d8: 83 ec 0c sub $0xc,%esp +801041db: 68 40 1d 11 80 push $0x80111d40 +801041e0: e8 1b 05 00 00 call 80104700 + release(lk); +801041e5: 89 34 24 mov %esi,(%esp) +801041e8: e8 b3 04 00 00 call 801046a0 + p->chan = chan; +801041ed: 89 7b 20 mov %edi,0x20(%ebx) + p->state = SLEEPING; +801041f0: c7 43 0c 02 00 00 00 movl $0x2,0xc(%ebx) + sched(); +801041f7: e8 34 fc ff ff call 80103e30 + p->chan = 0; +801041fc: c7 43 20 00 00 00 00 movl $0x0,0x20(%ebx) + release(&ptable.lock); +80104203: c7 04 24 40 1d 11 80 movl $0x80111d40,(%esp) +8010420a: e8 91 04 00 00 call 801046a0 + acquire(lk); +8010420f: 89 75 08 mov %esi,0x8(%ebp) +80104212: 83 c4 10 add $0x10,%esp +} +80104215: 8d 65 f4 lea -0xc(%ebp),%esp +80104218: 5b pop %ebx +80104219: 5e pop %esi +8010421a: 5f pop %edi +8010421b: 5d pop %ebp + acquire(lk); +8010421c: e9 df 04 00 00 jmp 80104700 +80104221: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + p->chan = chan; +80104228: 89 7b 20 mov %edi,0x20(%ebx) + p->state = SLEEPING; +8010422b: c7 43 0c 02 00 00 00 movl $0x2,0xc(%ebx) + sched(); +80104232: e8 f9 fb ff ff call 80103e30 + p->chan = 0; +80104237: c7 43 20 00 00 00 00 movl $0x0,0x20(%ebx) +} +8010423e: 8d 65 f4 lea -0xc(%ebp),%esp +80104241: 5b pop %ebx +80104242: 5e pop %esi +80104243: 5f pop %edi +80104244: 5d pop %ebp +80104245: c3 ret + panic("sleep without lk"); +80104246: 83 ec 0c sub $0xc,%esp +80104249: 68 ba 79 10 80 push $0x801079ba +8010424e: e8 3d c1 ff ff call 80100390 + panic("sleep"); +80104253: 83 ec 0c sub $0xc,%esp +80104256: 68 b4 79 10 80 push $0x801079b4 +8010425b: e8 30 c1 ff ff call 80100390 + +80104260 : + } + } +} + +// Wake up all processes sleeping on chan. +void wakeup(void *chan) { +80104260: 55 push %ebp +80104261: 89 e5 mov %esp,%ebp +80104263: 53 push %ebx +80104264: 83 ec 10 sub $0x10,%esp +80104267: 8b 5d 08 mov 0x8(%ebp),%ebx + acquire(&ptable.lock); +8010426a: 68 40 1d 11 80 push $0x80111d40 +8010426f: e8 8c 04 00 00 call 80104700 +80104274: 83 c4 10 add $0x10,%esp + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80104277: b8 74 1d 11 80 mov $0x80111d74,%eax +8010427c: eb 0c jmp 8010428a +8010427e: 66 90 xchg %ax,%ax +80104280: 83 c0 7c add $0x7c,%eax +80104283: 3d 74 3c 11 80 cmp $0x80113c74,%eax +80104288: 74 1c je 801042a6 + if (p->state == SLEEPING && p->chan == chan) { +8010428a: 83 78 0c 02 cmpl $0x2,0xc(%eax) +8010428e: 75 f0 jne 80104280 +80104290: 3b 58 20 cmp 0x20(%eax),%ebx +80104293: 75 eb jne 80104280 + p->state = RUNNABLE; +80104295: c7 40 0c 03 00 00 00 movl $0x3,0xc(%eax) + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +8010429c: 83 c0 7c add $0x7c,%eax +8010429f: 3d 74 3c 11 80 cmp $0x80113c74,%eax +801042a4: 75 e4 jne 8010428a + wakeup1(chan); + release(&ptable.lock); +801042a6: c7 45 08 40 1d 11 80 movl $0x80111d40,0x8(%ebp) +} +801042ad: 8b 5d fc mov -0x4(%ebp),%ebx +801042b0: c9 leave + release(&ptable.lock); +801042b1: e9 ea 03 00 00 jmp 801046a0 +801042b6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801042bd: 8d 76 00 lea 0x0(%esi),%esi + +801042c0 : + +// Kill the process with the given pid. +// Process won't exit until it returns +// to user space (see trap in trap.c). +int kill(int pid) { +801042c0: 55 push %ebp +801042c1: 89 e5 mov %esp,%ebp +801042c3: 53 push %ebx +801042c4: 83 ec 10 sub $0x10,%esp +801042c7: 8b 5d 08 mov 0x8(%ebp),%ebx + struct proc *p; + + acquire(&ptable.lock); +801042ca: 68 40 1d 11 80 push $0x80111d40 +801042cf: e8 2c 04 00 00 call 80104700 +801042d4: 83 c4 10 add $0x10,%esp + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +801042d7: b8 74 1d 11 80 mov $0x80111d74,%eax +801042dc: eb 0c jmp 801042ea +801042de: 66 90 xchg %ax,%ax +801042e0: 83 c0 7c add $0x7c,%eax +801042e3: 3d 74 3c 11 80 cmp $0x80113c74,%eax +801042e8: 74 36 je 80104320 + if (p->pid == pid) { +801042ea: 39 58 10 cmp %ebx,0x10(%eax) +801042ed: 75 f1 jne 801042e0 + p->killed = 1; + // Wake process from sleep if necessary. + if (p->state == SLEEPING) { +801042ef: 83 78 0c 02 cmpl $0x2,0xc(%eax) + p->killed = 1; +801042f3: c7 40 24 01 00 00 00 movl $0x1,0x24(%eax) + if (p->state == SLEEPING) { +801042fa: 75 07 jne 80104303 + p->state = RUNNABLE; +801042fc: c7 40 0c 03 00 00 00 movl $0x3,0xc(%eax) + } + release(&ptable.lock); +80104303: 83 ec 0c sub $0xc,%esp +80104306: 68 40 1d 11 80 push $0x80111d40 +8010430b: e8 90 03 00 00 call 801046a0 + return 0; + } + } + release(&ptable.lock); + return -1; +} +80104310: 8b 5d fc mov -0x4(%ebp),%ebx + return 0; +80104313: 83 c4 10 add $0x10,%esp +80104316: 31 c0 xor %eax,%eax +} +80104318: c9 leave +80104319: c3 ret +8010431a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + release(&ptable.lock); +80104320: 83 ec 0c sub $0xc,%esp +80104323: 68 40 1d 11 80 push $0x80111d40 +80104328: e8 73 03 00 00 call 801046a0 +} +8010432d: 8b 5d fc mov -0x4(%ebp),%ebx + return -1; +80104330: 83 c4 10 add $0x10,%esp +80104333: b8 ff ff ff ff mov $0xffffffff,%eax +} +80104338: c9 leave +80104339: c3 ret +8010433a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80104340 : + +// Print a process listing to console. For debugging. +// Runs when user types ^P on console. +// No lock to avoid wedging a stuck machine further. +void procdump(void) { +80104340: 55 push %ebp +80104341: 89 e5 mov %esp,%ebp +80104343: 57 push %edi +80104344: 56 push %esi +80104345: 8d 75 e8 lea -0x18(%ebp),%esi +80104348: 53 push %ebx +80104349: bb e0 1d 11 80 mov $0x80111de0,%ebx +8010434e: 83 ec 3c sub $0x3c,%esp +80104351: eb 24 jmp 80104377 +80104353: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104357: 90 nop + getcallerpcs((uint*)p->context->ebp + 2, pc); + for (i = 0; i < 10 && pc[i] != 0; i++) { + cprintf(" %p", pc[i]); + } + } + cprintf("\n"); +80104358: 83 ec 0c sub $0xc,%esp +8010435b: 68 4f 7d 10 80 push $0x80107d4f +80104360: e8 4b c3 ff ff call 801006b0 +80104365: 83 c4 10 add $0x10,%esp + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { +80104368: 83 c3 7c add $0x7c,%ebx +8010436b: 81 fb e0 3c 11 80 cmp $0x80113ce0,%ebx +80104371: 0f 84 81 00 00 00 je 801043f8 + if (p->state == UNUSED) { +80104377: 8b 43 a0 mov -0x60(%ebx),%eax +8010437a: 85 c0 test %eax,%eax +8010437c: 74 ea je 80104368 + state = "???"; +8010437e: ba cb 79 10 80 mov $0x801079cb,%edx + if (p->state >= 0 && p->state < NELEM(states) && states[p->state]) { +80104383: 83 f8 05 cmp $0x5,%eax +80104386: 77 11 ja 80104399 +80104388: 8b 14 85 2c 7a 10 80 mov -0x7fef85d4(,%eax,4),%edx + state = "???"; +8010438f: b8 cb 79 10 80 mov $0x801079cb,%eax +80104394: 85 d2 test %edx,%edx +80104396: 0f 44 d0 cmove %eax,%edx + cprintf("%d %s %s", p->pid, state, p->name); +80104399: 53 push %ebx +8010439a: 52 push %edx +8010439b: ff 73 a4 push -0x5c(%ebx) +8010439e: 68 cf 79 10 80 push $0x801079cf +801043a3: e8 08 c3 ff ff call 801006b0 + if (p->state == SLEEPING) { +801043a8: 83 c4 10 add $0x10,%esp +801043ab: 83 7b a0 02 cmpl $0x2,-0x60(%ebx) +801043af: 75 a7 jne 80104358 + getcallerpcs((uint*)p->context->ebp + 2, pc); +801043b1: 83 ec 08 sub $0x8,%esp +801043b4: 8d 45 c0 lea -0x40(%ebp),%eax +801043b7: 8d 7d c0 lea -0x40(%ebp),%edi +801043ba: 50 push %eax +801043bb: 8b 43 b0 mov -0x50(%ebx),%eax +801043be: 8b 40 0c mov 0xc(%eax),%eax +801043c1: 83 c0 08 add $0x8,%eax +801043c4: 50 push %eax +801043c5: e8 86 01 00 00 call 80104550 + for (i = 0; i < 10 && pc[i] != 0; i++) { +801043ca: 83 c4 10 add $0x10,%esp +801043cd: 8d 76 00 lea 0x0(%esi),%esi +801043d0: 8b 17 mov (%edi),%edx +801043d2: 85 d2 test %edx,%edx +801043d4: 74 82 je 80104358 + cprintf(" %p", pc[i]); +801043d6: 83 ec 08 sub $0x8,%esp + for (i = 0; i < 10 && pc[i] != 0; i++) { +801043d9: 83 c7 04 add $0x4,%edi + cprintf(" %p", pc[i]); +801043dc: 52 push %edx +801043dd: 68 21 74 10 80 push $0x80107421 +801043e2: e8 c9 c2 ff ff call 801006b0 + for (i = 0; i < 10 && pc[i] != 0; i++) { +801043e7: 83 c4 10 add $0x10,%esp +801043ea: 39 fe cmp %edi,%esi +801043ec: 75 e2 jne 801043d0 +801043ee: e9 65 ff ff ff jmp 80104358 +801043f3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801043f7: 90 nop + } +} +801043f8: 8d 65 f4 lea -0xc(%ebp),%esp +801043fb: 5b pop %ebx +801043fc: 5e pop %esi +801043fd: 5f pop %edi +801043fe: 5d pop %ebp +801043ff: c3 ret + +80104400 : +#include "mmu.h" +#include "proc.h" +#include "spinlock.h" +#include "sleeplock.h" + +void initsleeplock(struct sleeplock *lk, char *name) { +80104400: 55 push %ebp +80104401: 89 e5 mov %esp,%ebp +80104403: 53 push %ebx +80104404: 83 ec 0c sub $0xc,%esp +80104407: 8b 5d 08 mov 0x8(%ebp),%ebx + initlock(&lk->lk, "sleep lock"); +8010440a: 68 44 7a 10 80 push $0x80107a44 +8010440f: 8d 43 04 lea 0x4(%ebx),%eax +80104412: 50 push %eax +80104413: e8 18 01 00 00 call 80104530 + lk->name = name; +80104418: 8b 45 0c mov 0xc(%ebp),%eax + lk->locked = 0; +8010441b: c7 03 00 00 00 00 movl $0x0,(%ebx) + lk->pid = 0; +} +80104421: 83 c4 10 add $0x10,%esp + lk->pid = 0; +80104424: c7 43 3c 00 00 00 00 movl $0x0,0x3c(%ebx) + lk->name = name; +8010442b: 89 43 38 mov %eax,0x38(%ebx) +} +8010442e: 8b 5d fc mov -0x4(%ebp),%ebx +80104431: c9 leave +80104432: c3 ret +80104433: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010443a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80104440 : + +void acquiresleep(struct sleeplock *lk) { +80104440: 55 push %ebp +80104441: 89 e5 mov %esp,%ebp +80104443: 56 push %esi +80104444: 53 push %ebx +80104445: 8b 5d 08 mov 0x8(%ebp),%ebx + acquire(&lk->lk); +80104448: 8d 73 04 lea 0x4(%ebx),%esi +8010444b: 83 ec 0c sub $0xc,%esp +8010444e: 56 push %esi +8010444f: e8 ac 02 00 00 call 80104700 + while (lk->locked) { +80104454: 8b 13 mov (%ebx),%edx +80104456: 83 c4 10 add $0x10,%esp +80104459: 85 d2 test %edx,%edx +8010445b: 74 16 je 80104473 +8010445d: 8d 76 00 lea 0x0(%esi),%esi + sleep(lk, &lk->lk); +80104460: 83 ec 08 sub $0x8,%esp +80104463: 56 push %esi +80104464: 53 push %ebx +80104465: e8 36 fd ff ff call 801041a0 + while (lk->locked) { +8010446a: 8b 03 mov (%ebx),%eax +8010446c: 83 c4 10 add $0x10,%esp +8010446f: 85 c0 test %eax,%eax +80104471: 75 ed jne 80104460 + } + lk->locked = 1; +80104473: c7 03 01 00 00 00 movl $0x1,(%ebx) + lk->pid = myproc()->pid; +80104479: e8 52 f6 ff ff call 80103ad0 +8010447e: 8b 40 10 mov 0x10(%eax),%eax +80104481: 89 43 3c mov %eax,0x3c(%ebx) + release(&lk->lk); +80104484: 89 75 08 mov %esi,0x8(%ebp) +} +80104487: 8d 65 f8 lea -0x8(%ebp),%esp +8010448a: 5b pop %ebx +8010448b: 5e pop %esi +8010448c: 5d pop %ebp + release(&lk->lk); +8010448d: e9 0e 02 00 00 jmp 801046a0 +80104492: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104499: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +801044a0 : + +void releasesleep(struct sleeplock *lk) { +801044a0: 55 push %ebp +801044a1: 89 e5 mov %esp,%ebp +801044a3: 56 push %esi +801044a4: 53 push %ebx +801044a5: 8b 5d 08 mov 0x8(%ebp),%ebx + acquire(&lk->lk); +801044a8: 8d 73 04 lea 0x4(%ebx),%esi +801044ab: 83 ec 0c sub $0xc,%esp +801044ae: 56 push %esi +801044af: e8 4c 02 00 00 call 80104700 + lk->locked = 0; +801044b4: c7 03 00 00 00 00 movl $0x0,(%ebx) + lk->pid = 0; +801044ba: c7 43 3c 00 00 00 00 movl $0x0,0x3c(%ebx) + wakeup(lk); +801044c1: 89 1c 24 mov %ebx,(%esp) +801044c4: e8 97 fd ff ff call 80104260 + release(&lk->lk); +801044c9: 89 75 08 mov %esi,0x8(%ebp) +801044cc: 83 c4 10 add $0x10,%esp +} +801044cf: 8d 65 f8 lea -0x8(%ebp),%esp +801044d2: 5b pop %ebx +801044d3: 5e pop %esi +801044d4: 5d pop %ebp + release(&lk->lk); +801044d5: e9 c6 01 00 00 jmp 801046a0 +801044da: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +801044e0 : + +int holdingsleep(struct sleeplock *lk) { +801044e0: 55 push %ebp +801044e1: 89 e5 mov %esp,%ebp +801044e3: 57 push %edi +801044e4: 31 ff xor %edi,%edi +801044e6: 56 push %esi +801044e7: 53 push %ebx +801044e8: 83 ec 18 sub $0x18,%esp +801044eb: 8b 5d 08 mov 0x8(%ebp),%ebx + int r; + + acquire(&lk->lk); +801044ee: 8d 73 04 lea 0x4(%ebx),%esi +801044f1: 56 push %esi +801044f2: e8 09 02 00 00 call 80104700 + r = lk->locked && (lk->pid == myproc()->pid); +801044f7: 8b 03 mov (%ebx),%eax +801044f9: 83 c4 10 add $0x10,%esp +801044fc: 85 c0 test %eax,%eax +801044fe: 75 18 jne 80104518 + release(&lk->lk); +80104500: 83 ec 0c sub $0xc,%esp +80104503: 56 push %esi +80104504: e8 97 01 00 00 call 801046a0 + return r; +} +80104509: 8d 65 f4 lea -0xc(%ebp),%esp +8010450c: 89 f8 mov %edi,%eax +8010450e: 5b pop %ebx +8010450f: 5e pop %esi +80104510: 5f pop %edi +80104511: 5d pop %ebp +80104512: c3 ret +80104513: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104517: 90 nop + r = lk->locked && (lk->pid == myproc()->pid); +80104518: 8b 5b 3c mov 0x3c(%ebx),%ebx +8010451b: e8 b0 f5 ff ff call 80103ad0 +80104520: 39 58 10 cmp %ebx,0x10(%eax) +80104523: 0f 94 c0 sete %al +80104526: 0f b6 c0 movzbl %al,%eax +80104529: 89 c7 mov %eax,%edi +8010452b: eb d3 jmp 80104500 +8010452d: 66 90 xchg %ax,%ax +8010452f: 90 nop + +80104530 : +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "spinlock.h" + +void initlock(struct spinlock *lk, char *name) { +80104530: 55 push %ebp +80104531: 89 e5 mov %esp,%ebp +80104533: 8b 45 08 mov 0x8(%ebp),%eax + lk->name = name; +80104536: 8b 55 0c mov 0xc(%ebp),%edx + lk->locked = 0; +80104539: c7 00 00 00 00 00 movl $0x0,(%eax) + lk->name = name; +8010453f: 89 50 04 mov %edx,0x4(%eax) + lk->cpu = 0; +80104542: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) +} +80104549: 5d pop %ebp +8010454a: c3 ret +8010454b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010454f: 90 nop + +80104550 : + + popcli(); +} + +// Record the current call stack in pcs[] by following the %ebp chain. +void getcallerpcs(void *v, uint pcs[]) { +80104550: 55 push %ebp + uint *ebp; + int i; + + ebp = (uint*)v - 2; + for (i = 0; i < 10; i++) { +80104551: 31 d2 xor %edx,%edx +void getcallerpcs(void *v, uint pcs[]) { +80104553: 89 e5 mov %esp,%ebp +80104555: 53 push %ebx + ebp = (uint*)v - 2; +80104556: 8b 45 08 mov 0x8(%ebp),%eax +void getcallerpcs(void *v, uint pcs[]) { +80104559: 8b 4d 0c mov 0xc(%ebp),%ecx + ebp = (uint*)v - 2; +8010455c: 83 e8 08 sub $0x8,%eax + for (i = 0; i < 10; i++) { +8010455f: 90 nop + if (ebp == 0 || ebp < (uint*)KERNBASE || ebp == (uint*)0xffffffff) { +80104560: 8d 98 00 00 00 80 lea -0x80000000(%eax),%ebx +80104566: 81 fb fe ff ff 7f cmp $0x7ffffffe,%ebx +8010456c: 77 1a ja 80104588 + break; + } + pcs[i] = ebp[1]; // saved %eip +8010456e: 8b 58 04 mov 0x4(%eax),%ebx +80104571: 89 1c 91 mov %ebx,(%ecx,%edx,4) + for (i = 0; i < 10; i++) { +80104574: 83 c2 01 add $0x1,%edx + ebp = (uint*)ebp[0]; // saved %ebp +80104577: 8b 00 mov (%eax),%eax + for (i = 0; i < 10; i++) { +80104579: 83 fa 0a cmp $0xa,%edx +8010457c: 75 e2 jne 80104560 + } + for (; i < 10; i++) { + pcs[i] = 0; + } +} +8010457e: 8b 5d fc mov -0x4(%ebp),%ebx +80104581: c9 leave +80104582: c3 ret +80104583: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104587: 90 nop + for (; i < 10; i++) { +80104588: 8d 04 91 lea (%ecx,%edx,4),%eax +8010458b: 8d 51 28 lea 0x28(%ecx),%edx +8010458e: 66 90 xchg %ax,%ax + pcs[i] = 0; +80104590: c7 00 00 00 00 00 movl $0x0,(%eax) + for (; i < 10; i++) { +80104596: 83 c0 04 add $0x4,%eax +80104599: 39 d0 cmp %edx,%eax +8010459b: 75 f3 jne 80104590 +} +8010459d: 8b 5d fc mov -0x4(%ebp),%ebx +801045a0: c9 leave +801045a1: c3 ret +801045a2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801045a9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +801045b0 : + +// Pushcli/popcli are like cli/sti except that they are matched: +// it takes two popcli to undo two pushcli. Also, if interrupts +// are off, then pushcli, popcli leaves them off. + +void pushcli(void) { +801045b0: 55 push %ebp +801045b1: 89 e5 mov %esp,%ebp +801045b3: 53 push %ebx +801045b4: 83 ec 04 sub $0x4,%esp +801045b7: 9c pushf +801045b8: 5b pop %ebx + asm volatile ("cli"); +801045b9: fa cli + int eflags; + + eflags = readeflags(); + cli(); + if (mycpu()->ncli == 0) { +801045ba: e8 91 f4 ff ff call 80103a50 +801045bf: 8b 80 a4 00 00 00 mov 0xa4(%eax),%eax +801045c5: 85 c0 test %eax,%eax +801045c7: 74 17 je 801045e0 + mycpu()->intena = eflags & FL_IF; + } + mycpu()->ncli += 1; +801045c9: e8 82 f4 ff ff call 80103a50 +801045ce: 83 80 a4 00 00 00 01 addl $0x1,0xa4(%eax) +} +801045d5: 8b 5d fc mov -0x4(%ebp),%ebx +801045d8: c9 leave +801045d9: c3 ret +801045da: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + mycpu()->intena = eflags & FL_IF; +801045e0: e8 6b f4 ff ff call 80103a50 +801045e5: 81 e3 00 02 00 00 and $0x200,%ebx +801045eb: 89 98 a8 00 00 00 mov %ebx,0xa8(%eax) +801045f1: eb d6 jmp 801045c9 +801045f3: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801045fa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80104600 : + +void popcli(void) { +80104600: 55 push %ebp +80104601: 89 e5 mov %esp,%ebp +80104603: 83 ec 08 sub $0x8,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +80104606: 9c pushf +80104607: 58 pop %eax + if (readeflags() & FL_IF) { +80104608: f6 c4 02 test $0x2,%ah +8010460b: 75 35 jne 80104642 + panic("popcli - interruptible"); + } + if (--mycpu()->ncli < 0) { +8010460d: e8 3e f4 ff ff call 80103a50 +80104612: 83 a8 a4 00 00 00 01 subl $0x1,0xa4(%eax) +80104619: 78 34 js 8010464f + panic("popcli"); + } + if (mycpu()->ncli == 0 && mycpu()->intena) { +8010461b: e8 30 f4 ff ff call 80103a50 +80104620: 8b 90 a4 00 00 00 mov 0xa4(%eax),%edx +80104626: 85 d2 test %edx,%edx +80104628: 74 06 je 80104630 + sti(); + } +} +8010462a: c9 leave +8010462b: c3 ret +8010462c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (mycpu()->ncli == 0 && mycpu()->intena) { +80104630: e8 1b f4 ff ff call 80103a50 +80104635: 8b 80 a8 00 00 00 mov 0xa8(%eax),%eax +8010463b: 85 c0 test %eax,%eax +8010463d: 74 eb je 8010462a + asm volatile ("sti"); +8010463f: fb sti +} +80104640: c9 leave +80104641: c3 ret + panic("popcli - interruptible"); +80104642: 83 ec 0c sub $0xc,%esp +80104645: 68 4f 7a 10 80 push $0x80107a4f +8010464a: e8 41 bd ff ff call 80100390 + panic("popcli"); +8010464f: 83 ec 0c sub $0xc,%esp +80104652: 68 66 7a 10 80 push $0x80107a66 +80104657: e8 34 bd ff ff call 80100390 +8010465c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80104660 : +int holding(struct spinlock *lock) { +80104660: 55 push %ebp +80104661: 89 e5 mov %esp,%ebp +80104663: 56 push %esi +80104664: 53 push %ebx +80104665: 8b 75 08 mov 0x8(%ebp),%esi +80104668: 31 db xor %ebx,%ebx + pushcli(); +8010466a: e8 41 ff ff ff call 801045b0 + r = lock->locked && lock->cpu == mycpu(); +8010466f: 8b 06 mov (%esi),%eax +80104671: 85 c0 test %eax,%eax +80104673: 75 0b jne 80104680 + popcli(); +80104675: e8 86 ff ff ff call 80104600 +} +8010467a: 89 d8 mov %ebx,%eax +8010467c: 5b pop %ebx +8010467d: 5e pop %esi +8010467e: 5d pop %ebp +8010467f: c3 ret + r = lock->locked && lock->cpu == mycpu(); +80104680: 8b 5e 08 mov 0x8(%esi),%ebx +80104683: e8 c8 f3 ff ff call 80103a50 +80104688: 39 c3 cmp %eax,%ebx +8010468a: 0f 94 c3 sete %bl + popcli(); +8010468d: e8 6e ff ff ff call 80104600 + r = lock->locked && lock->cpu == mycpu(); +80104692: 0f b6 db movzbl %bl,%ebx +} +80104695: 89 d8 mov %ebx,%eax +80104697: 5b pop %ebx +80104698: 5e pop %esi +80104699: 5d pop %ebp +8010469a: c3 ret +8010469b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010469f: 90 nop + +801046a0 : +void release(struct spinlock *lk) { +801046a0: 55 push %ebp +801046a1: 89 e5 mov %esp,%ebp +801046a3: 56 push %esi +801046a4: 53 push %ebx +801046a5: 8b 5d 08 mov 0x8(%ebp),%ebx + pushcli(); +801046a8: e8 03 ff ff ff call 801045b0 + r = lock->locked && lock->cpu == mycpu(); +801046ad: 8b 03 mov (%ebx),%eax +801046af: 85 c0 test %eax,%eax +801046b1: 75 15 jne 801046c8 + popcli(); +801046b3: e8 48 ff ff ff call 80104600 + panic("release"); +801046b8: 83 ec 0c sub $0xc,%esp +801046bb: 68 6d 7a 10 80 push $0x80107a6d +801046c0: e8 cb bc ff ff call 80100390 +801046c5: 8d 76 00 lea 0x0(%esi),%esi + r = lock->locked && lock->cpu == mycpu(); +801046c8: 8b 73 08 mov 0x8(%ebx),%esi +801046cb: e8 80 f3 ff ff call 80103a50 +801046d0: 39 c6 cmp %eax,%esi +801046d2: 75 df jne 801046b3 + popcli(); +801046d4: e8 27 ff ff ff call 80104600 + lk->pcs[0] = 0; +801046d9: c7 43 0c 00 00 00 00 movl $0x0,0xc(%ebx) + lk->cpu = 0; +801046e0: c7 43 08 00 00 00 00 movl $0x0,0x8(%ebx) + __sync_synchronize(); +801046e7: f0 83 0c 24 00 lock orl $0x0,(%esp) + asm volatile ("movl $0, %0" : "+m" (lk->locked) :); +801046ec: c7 03 00 00 00 00 movl $0x0,(%ebx) +} +801046f2: 8d 65 f8 lea -0x8(%ebp),%esp +801046f5: 5b pop %ebx +801046f6: 5e pop %esi +801046f7: 5d pop %ebp + popcli(); +801046f8: e9 03 ff ff ff jmp 80104600 +801046fd: 8d 76 00 lea 0x0(%esi),%esi + +80104700 : +void acquire(struct spinlock *lk) { +80104700: 55 push %ebp +80104701: 89 e5 mov %esp,%ebp +80104703: 53 push %ebx +80104704: 83 ec 04 sub $0x4,%esp + pushcli(); // disable interrupts to avoid deadlock. +80104707: e8 a4 fe ff ff call 801045b0 + if (holding(lk)) { +8010470c: 8b 5d 08 mov 0x8(%ebp),%ebx + pushcli(); +8010470f: e8 9c fe ff ff call 801045b0 + r = lock->locked && lock->cpu == mycpu(); +80104714: 8b 03 mov (%ebx),%eax +80104716: 85 c0 test %eax,%eax +80104718: 75 7e jne 80104798 + popcli(); +8010471a: e8 e1 fe ff ff call 80104600 + asm volatile ("lock; xchgl %0, %1" : +8010471f: b9 01 00 00 00 mov $0x1,%ecx +80104724: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while (xchg(&lk->locked, 1) != 0) { +80104728: 8b 55 08 mov 0x8(%ebp),%edx +8010472b: 89 c8 mov %ecx,%eax +8010472d: f0 87 02 lock xchg %eax,(%edx) +80104730: 85 c0 test %eax,%eax +80104732: 75 f4 jne 80104728 + __sync_synchronize(); +80104734: f0 83 0c 24 00 lock orl $0x0,(%esp) + lk->cpu = mycpu(); +80104739: 8b 5d 08 mov 0x8(%ebp),%ebx +8010473c: e8 0f f3 ff ff call 80103a50 + getcallerpcs(&lk, lk->pcs); +80104741: 8b 4d 08 mov 0x8(%ebp),%ecx + ebp = (uint*)v - 2; +80104744: 89 ea mov %ebp,%edx + lk->cpu = mycpu(); +80104746: 89 43 08 mov %eax,0x8(%ebx) + for (i = 0; i < 10; i++) { +80104749: 31 c0 xor %eax,%eax +8010474b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010474f: 90 nop + if (ebp == 0 || ebp < (uint*)KERNBASE || ebp == (uint*)0xffffffff) { +80104750: 8d 9a 00 00 00 80 lea -0x80000000(%edx),%ebx +80104756: 81 fb fe ff ff 7f cmp $0x7ffffffe,%ebx +8010475c: 77 1a ja 80104778 + pcs[i] = ebp[1]; // saved %eip +8010475e: 8b 5a 04 mov 0x4(%edx),%ebx +80104761: 89 5c 81 0c mov %ebx,0xc(%ecx,%eax,4) + for (i = 0; i < 10; i++) { +80104765: 83 c0 01 add $0x1,%eax + ebp = (uint*)ebp[0]; // saved %ebp +80104768: 8b 12 mov (%edx),%edx + for (i = 0; i < 10; i++) { +8010476a: 83 f8 0a cmp $0xa,%eax +8010476d: 75 e1 jne 80104750 +} +8010476f: 8b 5d fc mov -0x4(%ebp),%ebx +80104772: c9 leave +80104773: c3 ret +80104774: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + for (; i < 10; i++) { +80104778: 8d 44 81 0c lea 0xc(%ecx,%eax,4),%eax +8010477c: 8d 51 34 lea 0x34(%ecx),%edx +8010477f: 90 nop + pcs[i] = 0; +80104780: c7 00 00 00 00 00 movl $0x0,(%eax) + for (; i < 10; i++) { +80104786: 83 c0 04 add $0x4,%eax +80104789: 39 c2 cmp %eax,%edx +8010478b: 75 f3 jne 80104780 +} +8010478d: 8b 5d fc mov -0x4(%ebp),%ebx +80104790: c9 leave +80104791: c3 ret +80104792: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + r = lock->locked && lock->cpu == mycpu(); +80104798: 8b 5b 08 mov 0x8(%ebx),%ebx +8010479b: e8 b0 f2 ff ff call 80103a50 +801047a0: 39 c3 cmp %eax,%ebx +801047a2: 0f 85 72 ff ff ff jne 8010471a + popcli(); +801047a8: e8 53 fe ff ff call 80104600 + panic("acquire"); +801047ad: 83 ec 0c sub $0xc,%esp +801047b0: 68 75 7a 10 80 push $0x80107a75 +801047b5: e8 d6 bb ff ff call 80100390 +801047ba: 66 90 xchg %ax,%ax +801047bc: 66 90 xchg %ax,%ax +801047be: 66 90 xchg %ax,%ax + +801047c0 : +#include "types.h" +#include "x86.h" + +void* memset(void *dst, int c, uint n) { +801047c0: 55 push %ebp +801047c1: 89 e5 mov %esp,%ebp +801047c3: 57 push %edi +801047c4: 8b 55 08 mov 0x8(%ebp),%edx +801047c7: 8b 4d 10 mov 0x10(%ebp),%ecx +801047ca: 53 push %ebx +801047cb: 8b 45 0c mov 0xc(%ebp),%eax + if ((int)dst % 4 == 0 && n % 4 == 0) { +801047ce: 89 d7 mov %edx,%edi +801047d0: 09 cf or %ecx,%edi +801047d2: 83 e7 03 and $0x3,%edi +801047d5: 75 29 jne 80104800 + c &= 0xFF; +801047d7: 0f b6 f8 movzbl %al,%edi + stosl(dst, (c << 24) | (c << 16) | (c << 8) | c, n / 4); +801047da: c1 e0 18 shl $0x18,%eax +801047dd: 89 fb mov %edi,%ebx +801047df: c1 e9 02 shr $0x2,%ecx +801047e2: c1 e3 10 shl $0x10,%ebx +801047e5: 09 d8 or %ebx,%eax +801047e7: 09 f8 or %edi,%eax +801047e9: c1 e7 08 shl $0x8,%edi +801047ec: 09 f8 or %edi,%eax + asm volatile ("cld; rep stosl" : +801047ee: 89 d7 mov %edx,%edi +801047f0: fc cld +801047f1: f3 ab rep stos %eax,%es:(%edi) + } + else { + stosb(dst, c, n); + } + return dst; +} +801047f3: 5b pop %ebx +801047f4: 89 d0 mov %edx,%eax +801047f6: 5f pop %edi +801047f7: 5d pop %ebp +801047f8: c3 ret +801047f9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + asm volatile ("cld; rep stosb" : +80104800: 89 d7 mov %edx,%edi +80104802: fc cld +80104803: f3 aa rep stos %al,%es:(%edi) +80104805: 5b pop %ebx +80104806: 89 d0 mov %edx,%eax +80104808: 5f pop %edi +80104809: 5d pop %ebp +8010480a: c3 ret +8010480b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010480f: 90 nop + +80104810 : + +int memcmp(const void *v1, const void *v2, uint n) { +80104810: 55 push %ebp +80104811: 89 e5 mov %esp,%ebp +80104813: 56 push %esi +80104814: 8b 75 10 mov 0x10(%ebp),%esi +80104817: 8b 55 08 mov 0x8(%ebp),%edx +8010481a: 53 push %ebx +8010481b: 8b 45 0c mov 0xc(%ebp),%eax + const uchar *s1, *s2; + + s1 = v1; + s2 = v2; + while (n-- > 0) { +8010481e: 85 f6 test %esi,%esi +80104820: 74 2e je 80104850 +80104822: 01 c6 add %eax,%esi +80104824: eb 14 jmp 8010483a +80104826: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010482d: 8d 76 00 lea 0x0(%esi),%esi + if (*s1 != *s2) { + return *s1 - *s2; + } + s1++, s2++; +80104830: 83 c0 01 add $0x1,%eax +80104833: 83 c2 01 add $0x1,%edx + while (n-- > 0) { +80104836: 39 f0 cmp %esi,%eax +80104838: 74 16 je 80104850 + if (*s1 != *s2) { +8010483a: 0f b6 0a movzbl (%edx),%ecx +8010483d: 0f b6 18 movzbl (%eax),%ebx +80104840: 38 d9 cmp %bl,%cl +80104842: 74 ec je 80104830 + return *s1 - *s2; +80104844: 0f b6 c1 movzbl %cl,%eax +80104847: 29 d8 sub %ebx,%eax + } + + return 0; +} +80104849: 5b pop %ebx +8010484a: 5e pop %esi +8010484b: 5d pop %ebp +8010484c: c3 ret +8010484d: 8d 76 00 lea 0x0(%esi),%esi +80104850: 5b pop %ebx + return 0; +80104851: 31 c0 xor %eax,%eax +} +80104853: 5e pop %esi +80104854: 5d pop %ebp +80104855: c3 ret +80104856: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010485d: 8d 76 00 lea 0x0(%esi),%esi + +80104860 : + +void* memmove(void *dst, const void *src, uint n) { +80104860: 55 push %ebp +80104861: 89 e5 mov %esp,%ebp +80104863: 57 push %edi +80104864: 8b 55 08 mov 0x8(%ebp),%edx +80104867: 8b 4d 10 mov 0x10(%ebp),%ecx +8010486a: 56 push %esi +8010486b: 8b 75 0c mov 0xc(%ebp),%esi + const char *s; + char *d; + + s = src; + d = dst; + if (s < d && s + n > d) { +8010486e: 39 d6 cmp %edx,%esi +80104870: 73 26 jae 80104898 +80104872: 8d 3c 0e lea (%esi,%ecx,1),%edi +80104875: 39 fa cmp %edi,%edx +80104877: 73 1f jae 80104898 +80104879: 8d 41 ff lea -0x1(%ecx),%eax + s += n; + d += n; + while (n-- > 0) { +8010487c: 85 c9 test %ecx,%ecx +8010487e: 74 0c je 8010488c + *--d = *--s; +80104880: 0f b6 0c 06 movzbl (%esi,%eax,1),%ecx +80104884: 88 0c 02 mov %cl,(%edx,%eax,1) + while (n-- > 0) { +80104887: 83 e8 01 sub $0x1,%eax +8010488a: 73 f4 jae 80104880 + *d++ = *s++; + } + } + + return dst; +} +8010488c: 5e pop %esi +8010488d: 89 d0 mov %edx,%eax +8010488f: 5f pop %edi +80104890: 5d pop %ebp +80104891: c3 ret +80104892: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + while (n-- > 0) { +80104898: 8d 04 0e lea (%esi,%ecx,1),%eax +8010489b: 89 d7 mov %edx,%edi +8010489d: 85 c9 test %ecx,%ecx +8010489f: 74 eb je 8010488c +801048a1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + *d++ = *s++; +801048a8: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { +801048a9: 39 c6 cmp %eax,%esi +801048ab: 75 fb jne 801048a8 +} +801048ad: 5e pop %esi +801048ae: 89 d0 mov %edx,%eax +801048b0: 5f pop %edi +801048b1: 5d pop %ebp +801048b2: c3 ret +801048b3: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801048ba: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +801048c0 : + +// memcpy exists to placate GCC. Use memmove. +void* memcpy(void *dst, const void *src, uint n) { + return memmove(dst, src, n); +801048c0: eb 9e jmp 80104860 +801048c2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801048c9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +801048d0 : +} + +int strncmp(const char *p, const char *q, uint n) { +801048d0: 55 push %ebp +801048d1: 89 e5 mov %esp,%ebp +801048d3: 56 push %esi +801048d4: 8b 75 10 mov 0x10(%ebp),%esi +801048d7: 8b 4d 08 mov 0x8(%ebp),%ecx +801048da: 53 push %ebx +801048db: 8b 55 0c mov 0xc(%ebp),%edx + while (n > 0 && *p && *p == *q) { +801048de: 85 f6 test %esi,%esi +801048e0: 74 2e je 80104910 +801048e2: 01 d6 add %edx,%esi +801048e4: eb 18 jmp 801048fe +801048e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801048ed: 8d 76 00 lea 0x0(%esi),%esi +801048f0: 38 d8 cmp %bl,%al +801048f2: 75 14 jne 80104908 + n--, p++, q++; +801048f4: 83 c2 01 add $0x1,%edx +801048f7: 83 c1 01 add $0x1,%ecx + while (n > 0 && *p && *p == *q) { +801048fa: 39 f2 cmp %esi,%edx +801048fc: 74 12 je 80104910 +801048fe: 0f b6 01 movzbl (%ecx),%eax +80104901: 0f b6 1a movzbl (%edx),%ebx +80104904: 84 c0 test %al,%al +80104906: 75 e8 jne 801048f0 + } + if (n == 0) { + return 0; + } + return (uchar) * p - (uchar) * q; +80104908: 29 d8 sub %ebx,%eax +} +8010490a: 5b pop %ebx +8010490b: 5e pop %esi +8010490c: 5d pop %ebp +8010490d: c3 ret +8010490e: 66 90 xchg %ax,%ax +80104910: 5b pop %ebx + return 0; +80104911: 31 c0 xor %eax,%eax +} +80104913: 5e pop %esi +80104914: 5d pop %ebp +80104915: c3 ret +80104916: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010491d: 8d 76 00 lea 0x0(%esi),%esi + +80104920 : + +char* strncpy(char *s, const char *t, int n) { +80104920: 55 push %ebp +80104921: 89 e5 mov %esp,%ebp +80104923: 57 push %edi +80104924: 56 push %esi +80104925: 8b 75 08 mov 0x8(%ebp),%esi +80104928: 53 push %ebx +80104929: 8b 4d 10 mov 0x10(%ebp),%ecx + char *os; + + os = s; + while (n-- > 0 && (*s++ = *t++) != 0) { +8010492c: 89 f0 mov %esi,%eax +8010492e: eb 15 jmp 80104945 +80104930: 83 45 0c 01 addl $0x1,0xc(%ebp) +80104934: 8b 7d 0c mov 0xc(%ebp),%edi +80104937: 83 c0 01 add $0x1,%eax +8010493a: 0f b6 57 ff movzbl -0x1(%edi),%edx +8010493e: 88 50 ff mov %dl,-0x1(%eax) +80104941: 84 d2 test %dl,%dl +80104943: 74 09 je 8010494e +80104945: 89 cb mov %ecx,%ebx +80104947: 83 e9 01 sub $0x1,%ecx +8010494a: 85 db test %ebx,%ebx +8010494c: 7f e2 jg 80104930 + ; + } + while (n-- > 0) { +8010494e: 89 c2 mov %eax,%edx +80104950: 85 c9 test %ecx,%ecx +80104952: 7e 17 jle 8010496b +80104954: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + *s++ = 0; +80104958: 83 c2 01 add $0x1,%edx +8010495b: 89 c1 mov %eax,%ecx +8010495d: c6 42 ff 00 movb $0x0,-0x1(%edx) + while (n-- > 0) { +80104961: 29 d1 sub %edx,%ecx +80104963: 8d 4c 0b ff lea -0x1(%ebx,%ecx,1),%ecx +80104967: 85 c9 test %ecx,%ecx +80104969: 7f ed jg 80104958 + } + return os; +} +8010496b: 5b pop %ebx +8010496c: 89 f0 mov %esi,%eax +8010496e: 5e pop %esi +8010496f: 5f pop %edi +80104970: 5d pop %ebp +80104971: c3 ret +80104972: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104979: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80104980 : + +// Like strncpy but guaranteed to NUL-terminate. +char* safestrcpy(char *s, const char *t, int n) { +80104980: 55 push %ebp +80104981: 89 e5 mov %esp,%ebp +80104983: 56 push %esi +80104984: 8b 55 10 mov 0x10(%ebp),%edx +80104987: 8b 75 08 mov 0x8(%ebp),%esi +8010498a: 53 push %ebx +8010498b: 8b 45 0c mov 0xc(%ebp),%eax + char *os; + + os = s; + if (n <= 0) { +8010498e: 85 d2 test %edx,%edx +80104990: 7e 25 jle 801049b7 +80104992: 8d 5c 10 ff lea -0x1(%eax,%edx,1),%ebx +80104996: 89 f2 mov %esi,%edx +80104998: eb 16 jmp 801049b0 +8010499a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + return os; + } + while (--n > 0 && (*s++ = *t++) != 0) { +801049a0: 0f b6 08 movzbl (%eax),%ecx +801049a3: 83 c0 01 add $0x1,%eax +801049a6: 83 c2 01 add $0x1,%edx +801049a9: 88 4a ff mov %cl,-0x1(%edx) +801049ac: 84 c9 test %cl,%cl +801049ae: 74 04 je 801049b4 +801049b0: 39 d8 cmp %ebx,%eax +801049b2: 75 ec jne 801049a0 + ; + } + *s = 0; +801049b4: c6 02 00 movb $0x0,(%edx) + return os; +} +801049b7: 89 f0 mov %esi,%eax +801049b9: 5b pop %ebx +801049ba: 5e pop %esi +801049bb: 5d pop %ebp +801049bc: c3 ret +801049bd: 8d 76 00 lea 0x0(%esi),%esi + +801049c0 : + +int strlen(const char *s) { +801049c0: 55 push %ebp + int n; + + for (n = 0; s[n]; n++) { +801049c1: 31 c0 xor %eax,%eax +int strlen(const char *s) { +801049c3: 89 e5 mov %esp,%ebp +801049c5: 8b 55 08 mov 0x8(%ebp),%edx + for (n = 0; s[n]; n++) { +801049c8: 80 3a 00 cmpb $0x0,(%edx) +801049cb: 74 0c je 801049d9 +801049cd: 8d 76 00 lea 0x0(%esi),%esi +801049d0: 83 c0 01 add $0x1,%eax +801049d3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) +801049d7: 75 f7 jne 801049d0 + ; + } + return n; +} +801049d9: 5d pop %ebp +801049da: c3 ret + +801049db : +# a struct context, and save its address in *old. +# Switch stacks to new and pop previously-saved registers. + +.globl swtch +swtch: + movl 4(%esp), %eax +801049db: 8b 44 24 04 mov 0x4(%esp),%eax + movl 8(%esp), %edx +801049df: 8b 54 24 08 mov 0x8(%esp),%edx + + # Save old callee-saved registers + pushl %ebp +801049e3: 55 push %ebp + pushl %ebx +801049e4: 53 push %ebx + pushl %esi +801049e5: 56 push %esi + pushl %edi +801049e6: 57 push %edi + + # Switch stacks + movl %esp, (%eax) +801049e7: 89 20 mov %esp,(%eax) + movl %edx, %esp +801049e9: 89 d4 mov %edx,%esp + + # Load new callee-saved registers + popl %edi +801049eb: 5f pop %edi + popl %esi +801049ec: 5e pop %esi + popl %ebx +801049ed: 5b pop %ebx + popl %ebp +801049ee: 5d pop %ebp + ret +801049ef: c3 ret + +801049f0 : +// Arguments on the stack, from the user call to the C +// library system call function. The saved user %esp points +// to a saved program counter, and then the first argument. + +// Fetch the int at addr from the current process. +int fetchint(uint addr, int *ip) { +801049f0: 55 push %ebp +801049f1: 89 e5 mov %esp,%ebp +801049f3: 53 push %ebx +801049f4: 83 ec 04 sub $0x4,%esp +801049f7: 8b 5d 08 mov 0x8(%ebp),%ebx + struct proc *curproc = myproc(); +801049fa: e8 d1 f0 ff ff call 80103ad0 + + if (addr >= curproc->sz || addr + 4 > curproc->sz) { +801049ff: 8b 00 mov (%eax),%eax +80104a01: 39 d8 cmp %ebx,%eax +80104a03: 76 1b jbe 80104a20 +80104a05: 8d 53 04 lea 0x4(%ebx),%edx +80104a08: 39 d0 cmp %edx,%eax +80104a0a: 72 14 jb 80104a20 + return -1; + } + *ip = *(int*)(addr); +80104a0c: 8b 45 0c mov 0xc(%ebp),%eax +80104a0f: 8b 13 mov (%ebx),%edx +80104a11: 89 10 mov %edx,(%eax) + return 0; +80104a13: 31 c0 xor %eax,%eax +} +80104a15: 8b 5d fc mov -0x4(%ebp),%ebx +80104a18: c9 leave +80104a19: c3 ret +80104a1a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + return -1; +80104a20: b8 ff ff ff ff mov $0xffffffff,%eax +80104a25: eb ee jmp 80104a15 +80104a27: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104a2e: 66 90 xchg %ax,%ax + +80104a30 : + +// Fetch the nul-terminated string at addr from the current process. +// Doesn't actually copy the string - just sets *pp to point at it. +// Returns length of string, not including nul. +int fetchstr(uint addr, char **pp) { +80104a30: 55 push %ebp +80104a31: 89 e5 mov %esp,%ebp +80104a33: 53 push %ebx +80104a34: 83 ec 04 sub $0x4,%esp +80104a37: 8b 5d 08 mov 0x8(%ebp),%ebx + char *s, *ep; + struct proc *curproc = myproc(); +80104a3a: e8 91 f0 ff ff call 80103ad0 + + if (addr >= curproc->sz) { +80104a3f: 39 18 cmp %ebx,(%eax) +80104a41: 76 2d jbe 80104a70 + return -1; + } + *pp = (char*)addr; +80104a43: 8b 55 0c mov 0xc(%ebp),%edx +80104a46: 89 1a mov %ebx,(%edx) + ep = (char*)curproc->sz; +80104a48: 8b 10 mov (%eax),%edx + for (s = *pp; s < ep; s++) { +80104a4a: 39 d3 cmp %edx,%ebx +80104a4c: 73 22 jae 80104a70 +80104a4e: 89 d8 mov %ebx,%eax +80104a50: eb 0d jmp 80104a5f +80104a52: 8d b6 00 00 00 00 lea 0x0(%esi),%esi +80104a58: 83 c0 01 add $0x1,%eax +80104a5b: 39 c2 cmp %eax,%edx +80104a5d: 76 11 jbe 80104a70 + if (*s == 0) { +80104a5f: 80 38 00 cmpb $0x0,(%eax) +80104a62: 75 f4 jne 80104a58 + return s - *pp; +80104a64: 29 d8 sub %ebx,%eax + } + } + return -1; +} +80104a66: 8b 5d fc mov -0x4(%ebp),%ebx +80104a69: c9 leave +80104a6a: c3 ret +80104a6b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104a6f: 90 nop +80104a70: 8b 5d fc mov -0x4(%ebp),%ebx + return -1; +80104a73: b8 ff ff ff ff mov $0xffffffff,%eax +} +80104a78: c9 leave +80104a79: c3 ret +80104a7a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80104a80 : + +// Fetch the nth 32-bit system call argument. +int argint(int n, int *ip) { +80104a80: 55 push %ebp +80104a81: 89 e5 mov %esp,%ebp +80104a83: 56 push %esi +80104a84: 53 push %ebx + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +80104a85: e8 46 f0 ff ff call 80103ad0 +80104a8a: 8b 55 08 mov 0x8(%ebp),%edx +80104a8d: 8b 40 18 mov 0x18(%eax),%eax +80104a90: 8b 40 44 mov 0x44(%eax),%eax +80104a93: 8d 1c 90 lea (%eax,%edx,4),%ebx + struct proc *curproc = myproc(); +80104a96: e8 35 f0 ff ff call 80103ad0 + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +80104a9b: 8d 73 04 lea 0x4(%ebx),%esi + if (addr >= curproc->sz || addr + 4 > curproc->sz) { +80104a9e: 8b 00 mov (%eax),%eax +80104aa0: 39 c6 cmp %eax,%esi +80104aa2: 73 1c jae 80104ac0 +80104aa4: 8d 53 08 lea 0x8(%ebx),%edx +80104aa7: 39 d0 cmp %edx,%eax +80104aa9: 72 15 jb 80104ac0 + *ip = *(int*)(addr); +80104aab: 8b 45 0c mov 0xc(%ebp),%eax +80104aae: 8b 53 04 mov 0x4(%ebx),%edx +80104ab1: 89 10 mov %edx,(%eax) + return 0; +80104ab3: 31 c0 xor %eax,%eax +} +80104ab5: 5b pop %ebx +80104ab6: 5e pop %esi +80104ab7: 5d pop %ebp +80104ab8: c3 ret +80104ab9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return -1; +80104ac0: b8 ff ff ff ff mov $0xffffffff,%eax + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +80104ac5: eb ee jmp 80104ab5 +80104ac7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104ace: 66 90 xchg %ax,%ax + +80104ad0 : + +// Fetch the nth word-sized system call argument as a pointer +// to a block of memory of size bytes. Check that the pointer +// lies within the process address space. +int argptr(int n, char **pp, int size) { +80104ad0: 55 push %ebp +80104ad1: 89 e5 mov %esp,%ebp +80104ad3: 57 push %edi +80104ad4: 56 push %esi +80104ad5: 53 push %ebx +80104ad6: 83 ec 0c sub $0xc,%esp + int i; + struct proc *curproc = myproc(); +80104ad9: e8 f2 ef ff ff call 80103ad0 +80104ade: 89 c6 mov %eax,%esi + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +80104ae0: e8 eb ef ff ff call 80103ad0 +80104ae5: 8b 55 08 mov 0x8(%ebp),%edx +80104ae8: 8b 40 18 mov 0x18(%eax),%eax +80104aeb: 8b 40 44 mov 0x44(%eax),%eax +80104aee: 8d 1c 90 lea (%eax,%edx,4),%ebx + struct proc *curproc = myproc(); +80104af1: e8 da ef ff ff call 80103ad0 + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +80104af6: 8d 7b 04 lea 0x4(%ebx),%edi + if (addr >= curproc->sz || addr + 4 > curproc->sz) { +80104af9: 8b 00 mov (%eax),%eax +80104afb: 39 c7 cmp %eax,%edi +80104afd: 73 31 jae 80104b30 +80104aff: 8d 4b 08 lea 0x8(%ebx),%ecx +80104b02: 39 c8 cmp %ecx,%eax +80104b04: 72 2a jb 80104b30 + + if (argint(n, &i) < 0) { + return -1; + } + if (size < 0 || (uint)i >= curproc->sz || (uint)i + size > curproc->sz) { +80104b06: 8b 55 10 mov 0x10(%ebp),%edx + *ip = *(int*)(addr); +80104b09: 8b 43 04 mov 0x4(%ebx),%eax + if (size < 0 || (uint)i >= curproc->sz || (uint)i + size > curproc->sz) { +80104b0c: 85 d2 test %edx,%edx +80104b0e: 78 20 js 80104b30 +80104b10: 8b 16 mov (%esi),%edx +80104b12: 39 c2 cmp %eax,%edx +80104b14: 76 1a jbe 80104b30 +80104b16: 8b 5d 10 mov 0x10(%ebp),%ebx +80104b19: 01 c3 add %eax,%ebx +80104b1b: 39 da cmp %ebx,%edx +80104b1d: 72 11 jb 80104b30 + return -1; + } + *pp = (char*)i; +80104b1f: 8b 55 0c mov 0xc(%ebp),%edx +80104b22: 89 02 mov %eax,(%edx) + return 0; +80104b24: 31 c0 xor %eax,%eax +} +80104b26: 83 c4 0c add $0xc,%esp +80104b29: 5b pop %ebx +80104b2a: 5e pop %esi +80104b2b: 5f pop %edi +80104b2c: 5d pop %ebp +80104b2d: c3 ret +80104b2e: 66 90 xchg %ax,%ax + return -1; +80104b30: b8 ff ff ff ff mov $0xffffffff,%eax +80104b35: eb ef jmp 80104b26 +80104b37: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104b3e: 66 90 xchg %ax,%ax + +80104b40 : + +// Fetch the nth word-sized system call argument as a string pointer. +// Check that the pointer is valid and the string is nul-terminated. +// (There is no shared writable memory, so the string can't change +// between this check and being used by the kernel.) +int argstr(int n, char **pp) { +80104b40: 55 push %ebp +80104b41: 89 e5 mov %esp,%ebp +80104b43: 56 push %esi +80104b44: 53 push %ebx + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +80104b45: e8 86 ef ff ff call 80103ad0 +80104b4a: 8b 55 08 mov 0x8(%ebp),%edx +80104b4d: 8b 40 18 mov 0x18(%eax),%eax +80104b50: 8b 40 44 mov 0x44(%eax),%eax +80104b53: 8d 1c 90 lea (%eax,%edx,4),%ebx + struct proc *curproc = myproc(); +80104b56: e8 75 ef ff ff call 80103ad0 + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +80104b5b: 8d 73 04 lea 0x4(%ebx),%esi + if (addr >= curproc->sz || addr + 4 > curproc->sz) { +80104b5e: 8b 00 mov (%eax),%eax +80104b60: 39 c6 cmp %eax,%esi +80104b62: 73 44 jae 80104ba8 +80104b64: 8d 53 08 lea 0x8(%ebx),%edx +80104b67: 39 d0 cmp %edx,%eax +80104b69: 72 3d jb 80104ba8 + *ip = *(int*)(addr); +80104b6b: 8b 5b 04 mov 0x4(%ebx),%ebx + struct proc *curproc = myproc(); +80104b6e: e8 5d ef ff ff call 80103ad0 + if (addr >= curproc->sz) { +80104b73: 3b 18 cmp (%eax),%ebx +80104b75: 73 31 jae 80104ba8 + *pp = (char*)addr; +80104b77: 8b 55 0c mov 0xc(%ebp),%edx +80104b7a: 89 1a mov %ebx,(%edx) + ep = (char*)curproc->sz; +80104b7c: 8b 10 mov (%eax),%edx + for (s = *pp; s < ep; s++) { +80104b7e: 39 d3 cmp %edx,%ebx +80104b80: 73 26 jae 80104ba8 +80104b82: 89 d8 mov %ebx,%eax +80104b84: eb 11 jmp 80104b97 +80104b86: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104b8d: 8d 76 00 lea 0x0(%esi),%esi +80104b90: 83 c0 01 add $0x1,%eax +80104b93: 39 c2 cmp %eax,%edx +80104b95: 76 11 jbe 80104ba8 + if (*s == 0) { +80104b97: 80 38 00 cmpb $0x0,(%eax) +80104b9a: 75 f4 jne 80104b90 + return s - *pp; +80104b9c: 29 d8 sub %ebx,%eax + int addr; + if (argint(n, &addr) < 0) { + return -1; + } + return fetchstr(addr, pp); +} +80104b9e: 5b pop %ebx +80104b9f: 5e pop %esi +80104ba0: 5d pop %ebp +80104ba1: c3 ret +80104ba2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi +80104ba8: 5b pop %ebx + return -1; +80104ba9: b8 ff ff ff ff mov $0xffffffff,%eax +} +80104bae: 5e pop %esi +80104baf: 5d pop %ebp +80104bb0: c3 ret +80104bb1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104bb8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104bbf: 90 nop + +80104bc0 : + +void syscall(void) { +80104bc0: 55 push %ebp +80104bc1: 89 e5 mov %esp,%ebp +80104bc3: 53 push %ebx +80104bc4: 83 ec 04 sub $0x4,%esp + int num; + struct proc *curproc = myproc(); +80104bc7: e8 04 ef ff ff call 80103ad0 +80104bcc: 89 c3 mov %eax,%ebx + + num = curproc->tf->eax; +80104bce: 8b 40 18 mov 0x18(%eax),%eax +80104bd1: 8b 40 1c mov 0x1c(%eax),%eax + if (num > 0 && num < NELEM(syscalls) && syscalls[num]) { +80104bd4: 8d 50 ff lea -0x1(%eax),%edx +80104bd7: 83 fa 17 cmp $0x17,%edx +80104bda: 77 24 ja 80104c00 +80104bdc: 8b 14 85 a0 7a 10 80 mov -0x7fef8560(,%eax,4),%edx +80104be3: 85 d2 test %edx,%edx +80104be5: 74 19 je 80104c00 + curproc->tf->eax = syscalls[num](); +80104be7: ff d2 call *%edx +80104be9: 89 c2 mov %eax,%edx +80104beb: 8b 43 18 mov 0x18(%ebx),%eax +80104bee: 89 50 1c mov %edx,0x1c(%eax) + else { + cprintf("%d %s: unknown sys call %d\n", + curproc->pid, curproc->name, num); + curproc->tf->eax = -1; + } +} +80104bf1: 8b 5d fc mov -0x4(%ebp),%ebx +80104bf4: c9 leave +80104bf5: c3 ret +80104bf6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104bfd: 8d 76 00 lea 0x0(%esi),%esi + cprintf("%d %s: unknown sys call %d\n", +80104c00: 50 push %eax + curproc->pid, curproc->name, num); +80104c01: 8d 43 6c lea 0x6c(%ebx),%eax + cprintf("%d %s: unknown sys call %d\n", +80104c04: 50 push %eax +80104c05: ff 73 10 push 0x10(%ebx) +80104c08: 68 7d 7a 10 80 push $0x80107a7d +80104c0d: e8 9e ba ff ff call 801006b0 + curproc->tf->eax = -1; +80104c12: 8b 43 18 mov 0x18(%ebx),%eax +80104c15: 83 c4 10 add $0x10,%esp +80104c18: c7 40 1c ff ff ff ff movl $0xffffffff,0x1c(%eax) +} +80104c1f: 8b 5d fc mov -0x4(%ebp),%ebx +80104c22: c9 leave +80104c23: c3 ret +80104c24: 66 90 xchg %ax,%ax +80104c26: 66 90 xchg %ax,%ax +80104c28: 66 90 xchg %ax,%ax +80104c2a: 66 90 xchg %ax,%ax +80104c2c: 66 90 xchg %ax,%ax +80104c2e: 66 90 xchg %ax,%ax + +80104c30 : + end_op(); + + return 0; +} + +static struct inode* create(char *path, short type, short major, short minor) { +80104c30: 55 push %ebp +80104c31: 89 e5 mov %esp,%ebp +80104c33: 57 push %edi +80104c34: 56 push %esi + struct inode *ip, *dp; + char name[DIRSIZ]; + + if ((dp = nameiparent(path, name)) == 0) { +80104c35: 8d 7d da lea -0x26(%ebp),%edi +static struct inode* create(char *path, short type, short major, short minor) { +80104c38: 53 push %ebx +80104c39: 83 ec 34 sub $0x34,%esp +80104c3c: 89 4d d0 mov %ecx,-0x30(%ebp) +80104c3f: 8b 4d 08 mov 0x8(%ebp),%ecx + if ((dp = nameiparent(path, name)) == 0) { +80104c42: 57 push %edi +80104c43: 50 push %eax +static struct inode* create(char *path, short type, short major, short minor) { +80104c44: 89 55 d4 mov %edx,-0x2c(%ebp) +80104c47: 89 4d cc mov %ecx,-0x34(%ebp) + if ((dp = nameiparent(path, name)) == 0) { +80104c4a: e8 91 d5 ff ff call 801021e0 +80104c4f: 83 c4 10 add $0x10,%esp +80104c52: 85 c0 test %eax,%eax +80104c54: 0f 84 46 01 00 00 je 80104da0 + return 0; + } + ilock(dp); +80104c5a: 83 ec 0c sub $0xc,%esp +80104c5d: 89 c3 mov %eax,%ebx +80104c5f: 50 push %eax +80104c60: e8 3b cc ff ff call 801018a0 + + if ((ip = dirlookup(dp, name, 0)) != 0) { +80104c65: 83 c4 0c add $0xc,%esp +80104c68: 6a 00 push $0x0 +80104c6a: 57 push %edi +80104c6b: 53 push %ebx +80104c6c: e8 8f d1 ff ff call 80101e00 +80104c71: 83 c4 10 add $0x10,%esp +80104c74: 89 c6 mov %eax,%esi +80104c76: 85 c0 test %eax,%eax +80104c78: 74 56 je 80104cd0 + iunlockput(dp); +80104c7a: 83 ec 0c sub $0xc,%esp +80104c7d: 53 push %ebx +80104c7e: e8 ad ce ff ff call 80101b30 + ilock(ip); +80104c83: 89 34 24 mov %esi,(%esp) +80104c86: e8 15 cc ff ff call 801018a0 + if (type == T_FILE && ip->type == T_FILE) { +80104c8b: 83 c4 10 add $0x10,%esp +80104c8e: 66 83 7d d4 02 cmpw $0x2,-0x2c(%ebp) +80104c93: 75 1b jne 80104cb0 +80104c95: 66 83 7e 50 02 cmpw $0x2,0x50(%esi) +80104c9a: 75 14 jne 80104cb0 + } + + iunlockput(dp); + + return ip; +} +80104c9c: 8d 65 f4 lea -0xc(%ebp),%esp +80104c9f: 89 f0 mov %esi,%eax +80104ca1: 5b pop %ebx +80104ca2: 5e pop %esi +80104ca3: 5f pop %edi +80104ca4: 5d pop %ebp +80104ca5: c3 ret +80104ca6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104cad: 8d 76 00 lea 0x0(%esi),%esi + iunlockput(ip); +80104cb0: 83 ec 0c sub $0xc,%esp +80104cb3: 56 push %esi + return 0; +80104cb4: 31 f6 xor %esi,%esi + iunlockput(ip); +80104cb6: e8 75 ce ff ff call 80101b30 + return 0; +80104cbb: 83 c4 10 add $0x10,%esp +} +80104cbe: 8d 65 f4 lea -0xc(%ebp),%esp +80104cc1: 89 f0 mov %esi,%eax +80104cc3: 5b pop %ebx +80104cc4: 5e pop %esi +80104cc5: 5f pop %edi +80104cc6: 5d pop %ebp +80104cc7: c3 ret +80104cc8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104ccf: 90 nop + if ((ip = ialloc(dp->dev, type)) == 0) { +80104cd0: 0f bf 45 d4 movswl -0x2c(%ebp),%eax +80104cd4: 83 ec 08 sub $0x8,%esp +80104cd7: 50 push %eax +80104cd8: ff 33 push (%ebx) +80104cda: e8 51 ca ff ff call 80101730 +80104cdf: 83 c4 10 add $0x10,%esp +80104ce2: 89 c6 mov %eax,%esi +80104ce4: 85 c0 test %eax,%eax +80104ce6: 0f 84 cd 00 00 00 je 80104db9 + ilock(ip); +80104cec: 83 ec 0c sub $0xc,%esp +80104cef: 50 push %eax +80104cf0: e8 ab cb ff ff call 801018a0 + ip->major = major; +80104cf5: 0f b7 45 d0 movzwl -0x30(%ebp),%eax +80104cf9: 66 89 46 52 mov %ax,0x52(%esi) + ip->minor = minor; +80104cfd: 0f b7 45 cc movzwl -0x34(%ebp),%eax +80104d01: 66 89 46 54 mov %ax,0x54(%esi) + ip->nlink = 1; +80104d05: b8 01 00 00 00 mov $0x1,%eax +80104d0a: 66 89 46 56 mov %ax,0x56(%esi) + iupdate(ip); +80104d0e: 89 34 24 mov %esi,(%esp) +80104d11: e8 da ca ff ff call 801017f0 + if (type == T_DIR) { // Create . and .. entries. +80104d16: 83 c4 10 add $0x10,%esp +80104d19: 66 83 7d d4 01 cmpw $0x1,-0x2c(%ebp) +80104d1e: 74 30 je 80104d50 + if (dirlink(dp, name, ip->inum) < 0) { +80104d20: 83 ec 04 sub $0x4,%esp +80104d23: ff 76 04 push 0x4(%esi) +80104d26: 57 push %edi +80104d27: 53 push %ebx +80104d28: e8 d3 d3 ff ff call 80102100 +80104d2d: 83 c4 10 add $0x10,%esp +80104d30: 85 c0 test %eax,%eax +80104d32: 78 78 js 80104dac + iunlockput(dp); +80104d34: 83 ec 0c sub $0xc,%esp +80104d37: 53 push %ebx +80104d38: e8 f3 cd ff ff call 80101b30 + return ip; +80104d3d: 83 c4 10 add $0x10,%esp +} +80104d40: 8d 65 f4 lea -0xc(%ebp),%esp +80104d43: 89 f0 mov %esi,%eax +80104d45: 5b pop %ebx +80104d46: 5e pop %esi +80104d47: 5f pop %edi +80104d48: 5d pop %ebp +80104d49: c3 ret +80104d4a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + iupdate(dp); +80104d50: 83 ec 0c sub $0xc,%esp + dp->nlink++; // for ".." +80104d53: 66 83 43 56 01 addw $0x1,0x56(%ebx) + iupdate(dp); +80104d58: 53 push %ebx +80104d59: e8 92 ca ff ff call 801017f0 + if (dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0) { +80104d5e: 83 c4 0c add $0xc,%esp +80104d61: ff 76 04 push 0x4(%esi) +80104d64: 68 20 7b 10 80 push $0x80107b20 +80104d69: 56 push %esi +80104d6a: e8 91 d3 ff ff call 80102100 +80104d6f: 83 c4 10 add $0x10,%esp +80104d72: 85 c0 test %eax,%eax +80104d74: 78 18 js 80104d8e +80104d76: 83 ec 04 sub $0x4,%esp +80104d79: ff 73 04 push 0x4(%ebx) +80104d7c: 68 1f 7b 10 80 push $0x80107b1f +80104d81: 56 push %esi +80104d82: e8 79 d3 ff ff call 80102100 +80104d87: 83 c4 10 add $0x10,%esp +80104d8a: 85 c0 test %eax,%eax +80104d8c: 79 92 jns 80104d20 + panic("create dots"); +80104d8e: 83 ec 0c sub $0xc,%esp +80104d91: 68 13 7b 10 80 push $0x80107b13 +80104d96: e8 f5 b5 ff ff call 80100390 +80104d9b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104d9f: 90 nop +} +80104da0: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; +80104da3: 31 f6 xor %esi,%esi +} +80104da5: 5b pop %ebx +80104da6: 89 f0 mov %esi,%eax +80104da8: 5e pop %esi +80104da9: 5f pop %edi +80104daa: 5d pop %ebp +80104dab: c3 ret + panic("create: dirlink"); +80104dac: 83 ec 0c sub $0xc,%esp +80104daf: 68 22 7b 10 80 push $0x80107b22 +80104db4: e8 d7 b5 ff ff call 80100390 + panic("create: ialloc"); +80104db9: 83 ec 0c sub $0xc,%esp +80104dbc: 68 04 7b 10 80 push $0x80107b04 +80104dc1: e8 ca b5 ff ff call 80100390 +80104dc6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104dcd: 8d 76 00 lea 0x0(%esi),%esi + +80104dd0 : +int sys_dup(void) { +80104dd0: 55 push %ebp +80104dd1: 89 e5 mov %esp,%ebp +80104dd3: 56 push %esi +80104dd4: 53 push %ebx + if (argint(n, &fd) < 0) { +80104dd5: 8d 45 f4 lea -0xc(%ebp),%eax +int sys_dup(void) { +80104dd8: 83 ec 18 sub $0x18,%esp + if (argint(n, &fd) < 0) { +80104ddb: 50 push %eax +80104ddc: 6a 00 push $0x0 +80104dde: e8 9d fc ff ff call 80104a80 +80104de3: 83 c4 10 add $0x10,%esp +80104de6: 85 c0 test %eax,%eax +80104de8: 78 36 js 80104e20 + if (fd < 0 || fd >= NOFILE || (f = myproc()->ofile[fd]) == 0) { +80104dea: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +80104dee: 77 30 ja 80104e20 +80104df0: e8 db ec ff ff call 80103ad0 +80104df5: 8b 55 f4 mov -0xc(%ebp),%edx +80104df8: 8b 74 90 28 mov 0x28(%eax,%edx,4),%esi +80104dfc: 85 f6 test %esi,%esi +80104dfe: 74 20 je 80104e20 + struct proc *curproc = myproc(); +80104e00: e8 cb ec ff ff call 80103ad0 + for (fd = 0; fd < NOFILE; fd++) { +80104e05: 31 db xor %ebx,%ebx +80104e07: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80104e0e: 66 90 xchg %ax,%ax + if (curproc->ofile[fd] == 0) { +80104e10: 8b 54 98 28 mov 0x28(%eax,%ebx,4),%edx +80104e14: 85 d2 test %edx,%edx +80104e16: 74 18 je 80104e30 + for (fd = 0; fd < NOFILE; fd++) { +80104e18: 83 c3 01 add $0x1,%ebx +80104e1b: 83 fb 10 cmp $0x10,%ebx +80104e1e: 75 f0 jne 80104e10 +} +80104e20: 8d 65 f8 lea -0x8(%ebp),%esp + return -1; +80104e23: bb ff ff ff ff mov $0xffffffff,%ebx +} +80104e28: 89 d8 mov %ebx,%eax +80104e2a: 5b pop %ebx +80104e2b: 5e pop %esi +80104e2c: 5d pop %ebp +80104e2d: c3 ret +80104e2e: 66 90 xchg %ax,%ax + filedup(f); +80104e30: 83 ec 0c sub $0xc,%esp + curproc->ofile[fd] = f; +80104e33: 89 74 98 28 mov %esi,0x28(%eax,%ebx,4) + filedup(f); +80104e37: 56 push %esi +80104e38: e8 83 c1 ff ff call 80100fc0 + return fd; +80104e3d: 83 c4 10 add $0x10,%esp +} +80104e40: 8d 65 f8 lea -0x8(%ebp),%esp +80104e43: 89 d8 mov %ebx,%eax +80104e45: 5b pop %ebx +80104e46: 5e pop %esi +80104e47: 5d pop %ebp +80104e48: c3 ret +80104e49: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80104e50 : +int sys_read(void) { +80104e50: 55 push %ebp +80104e51: 89 e5 mov %esp,%ebp +80104e53: 56 push %esi +80104e54: 53 push %ebx + if (argint(n, &fd) < 0) { +80104e55: 8d 5d f4 lea -0xc(%ebp),%ebx +int sys_read(void) { +80104e58: 83 ec 18 sub $0x18,%esp + if (argint(n, &fd) < 0) { +80104e5b: 53 push %ebx +80104e5c: 6a 00 push $0x0 +80104e5e: e8 1d fc ff ff call 80104a80 +80104e63: 83 c4 10 add $0x10,%esp +80104e66: 85 c0 test %eax,%eax +80104e68: 78 5e js 80104ec8 + if (fd < 0 || fd >= NOFILE || (f = myproc()->ofile[fd]) == 0) { +80104e6a: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +80104e6e: 77 58 ja 80104ec8 +80104e70: e8 5b ec ff ff call 80103ad0 +80104e75: 8b 55 f4 mov -0xc(%ebp),%edx +80104e78: 8b 74 90 28 mov 0x28(%eax,%edx,4),%esi +80104e7c: 85 f6 test %esi,%esi +80104e7e: 74 48 je 80104ec8 + if (argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) { +80104e80: 83 ec 08 sub $0x8,%esp +80104e83: 8d 45 f0 lea -0x10(%ebp),%eax +80104e86: 50 push %eax +80104e87: 6a 02 push $0x2 +80104e89: e8 f2 fb ff ff call 80104a80 +80104e8e: 83 c4 10 add $0x10,%esp +80104e91: 85 c0 test %eax,%eax +80104e93: 78 33 js 80104ec8 +80104e95: 83 ec 04 sub $0x4,%esp +80104e98: ff 75 f0 push -0x10(%ebp) +80104e9b: 53 push %ebx +80104e9c: 6a 01 push $0x1 +80104e9e: e8 2d fc ff ff call 80104ad0 +80104ea3: 83 c4 10 add $0x10,%esp +80104ea6: 85 c0 test %eax,%eax +80104ea8: 78 1e js 80104ec8 + return fileread(f, p, n); +80104eaa: 83 ec 04 sub $0x4,%esp +80104ead: ff 75 f0 push -0x10(%ebp) +80104eb0: ff 75 f4 push -0xc(%ebp) +80104eb3: 56 push %esi +80104eb4: e8 87 c2 ff ff call 80101140 +80104eb9: 83 c4 10 add $0x10,%esp +} +80104ebc: 8d 65 f8 lea -0x8(%ebp),%esp +80104ebf: 5b pop %ebx +80104ec0: 5e pop %esi +80104ec1: 5d pop %ebp +80104ec2: c3 ret +80104ec3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104ec7: 90 nop + return -1; +80104ec8: b8 ff ff ff ff mov $0xffffffff,%eax +80104ecd: eb ed jmp 80104ebc +80104ecf: 90 nop + +80104ed0 : +int sys_write(void) { +80104ed0: 55 push %ebp +80104ed1: 89 e5 mov %esp,%ebp +80104ed3: 56 push %esi +80104ed4: 53 push %ebx + if (argint(n, &fd) < 0) { +80104ed5: 8d 5d f4 lea -0xc(%ebp),%ebx +int sys_write(void) { +80104ed8: 83 ec 18 sub $0x18,%esp + if (argint(n, &fd) < 0) { +80104edb: 53 push %ebx +80104edc: 6a 00 push $0x0 +80104ede: e8 9d fb ff ff call 80104a80 +80104ee3: 83 c4 10 add $0x10,%esp +80104ee6: 85 c0 test %eax,%eax +80104ee8: 78 5e js 80104f48 + if (fd < 0 || fd >= NOFILE || (f = myproc()->ofile[fd]) == 0) { +80104eea: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +80104eee: 77 58 ja 80104f48 +80104ef0: e8 db eb ff ff call 80103ad0 +80104ef5: 8b 55 f4 mov -0xc(%ebp),%edx +80104ef8: 8b 74 90 28 mov 0x28(%eax,%edx,4),%esi +80104efc: 85 f6 test %esi,%esi +80104efe: 74 48 je 80104f48 + if (argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) { +80104f00: 83 ec 08 sub $0x8,%esp +80104f03: 8d 45 f0 lea -0x10(%ebp),%eax +80104f06: 50 push %eax +80104f07: 6a 02 push $0x2 +80104f09: e8 72 fb ff ff call 80104a80 +80104f0e: 83 c4 10 add $0x10,%esp +80104f11: 85 c0 test %eax,%eax +80104f13: 78 33 js 80104f48 +80104f15: 83 ec 04 sub $0x4,%esp +80104f18: ff 75 f0 push -0x10(%ebp) +80104f1b: 53 push %ebx +80104f1c: 6a 01 push $0x1 +80104f1e: e8 ad fb ff ff call 80104ad0 +80104f23: 83 c4 10 add $0x10,%esp +80104f26: 85 c0 test %eax,%eax +80104f28: 78 1e js 80104f48 + return filewrite(f, p, n); +80104f2a: 83 ec 04 sub $0x4,%esp +80104f2d: ff 75 f0 push -0x10(%ebp) +80104f30: ff 75 f4 push -0xc(%ebp) +80104f33: 56 push %esi +80104f34: e8 97 c2 ff ff call 801011d0 +80104f39: 83 c4 10 add $0x10,%esp +} +80104f3c: 8d 65 f8 lea -0x8(%ebp),%esp +80104f3f: 5b pop %ebx +80104f40: 5e pop %esi +80104f41: 5d pop %ebp +80104f42: c3 ret +80104f43: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80104f47: 90 nop + return -1; +80104f48: b8 ff ff ff ff mov $0xffffffff,%eax +80104f4d: eb ed jmp 80104f3c +80104f4f: 90 nop + +80104f50 : +int sys_close(void) { +80104f50: 55 push %ebp +80104f51: 89 e5 mov %esp,%ebp +80104f53: 56 push %esi +80104f54: 53 push %ebx + if (argint(n, &fd) < 0) { +80104f55: 8d 45 f4 lea -0xc(%ebp),%eax +int sys_close(void) { +80104f58: 83 ec 18 sub $0x18,%esp + if (argint(n, &fd) < 0) { +80104f5b: 50 push %eax +80104f5c: 6a 00 push $0x0 +80104f5e: e8 1d fb ff ff call 80104a80 +80104f63: 83 c4 10 add $0x10,%esp +80104f66: 85 c0 test %eax,%eax +80104f68: 78 3e js 80104fa8 + if (fd < 0 || fd >= NOFILE || (f = myproc()->ofile[fd]) == 0) { +80104f6a: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +80104f6e: 77 38 ja 80104fa8 +80104f70: e8 5b eb ff ff call 80103ad0 +80104f75: 8b 55 f4 mov -0xc(%ebp),%edx +80104f78: 8d 5a 08 lea 0x8(%edx),%ebx +80104f7b: 8b 74 98 08 mov 0x8(%eax,%ebx,4),%esi +80104f7f: 85 f6 test %esi,%esi +80104f81: 74 25 je 80104fa8 + myproc()->ofile[fd] = 0; +80104f83: e8 48 eb ff ff call 80103ad0 + fileclose(f); +80104f88: 83 ec 0c sub $0xc,%esp + myproc()->ofile[fd] = 0; +80104f8b: c7 44 98 08 00 00 00 movl $0x0,0x8(%eax,%ebx,4) +80104f92: 00 + fileclose(f); +80104f93: 56 push %esi +80104f94: e8 77 c0 ff ff call 80101010 + return 0; +80104f99: 83 c4 10 add $0x10,%esp +80104f9c: 31 c0 xor %eax,%eax +} +80104f9e: 8d 65 f8 lea -0x8(%ebp),%esp +80104fa1: 5b pop %ebx +80104fa2: 5e pop %esi +80104fa3: 5d pop %ebp +80104fa4: c3 ret +80104fa5: 8d 76 00 lea 0x0(%esi),%esi + return -1; +80104fa8: b8 ff ff ff ff mov $0xffffffff,%eax +80104fad: eb ef jmp 80104f9e +80104faf: 90 nop + +80104fb0 : +int sys_fstat(void) { +80104fb0: 55 push %ebp +80104fb1: 89 e5 mov %esp,%ebp +80104fb3: 56 push %esi +80104fb4: 53 push %ebx + if (argint(n, &fd) < 0) { +80104fb5: 8d 5d f4 lea -0xc(%ebp),%ebx +int sys_fstat(void) { +80104fb8: 83 ec 18 sub $0x18,%esp + if (argint(n, &fd) < 0) { +80104fbb: 53 push %ebx +80104fbc: 6a 00 push $0x0 +80104fbe: e8 bd fa ff ff call 80104a80 +80104fc3: 83 c4 10 add $0x10,%esp +80104fc6: 85 c0 test %eax,%eax +80104fc8: 78 46 js 80105010 + if (fd < 0 || fd >= NOFILE || (f = myproc()->ofile[fd]) == 0) { +80104fca: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +80104fce: 77 40 ja 80105010 +80104fd0: e8 fb ea ff ff call 80103ad0 +80104fd5: 8b 55 f4 mov -0xc(%ebp),%edx +80104fd8: 8b 74 90 28 mov 0x28(%eax,%edx,4),%esi +80104fdc: 85 f6 test %esi,%esi +80104fde: 74 30 je 80105010 + if (argfd(0, 0, &f) < 0 || argptr(1, (void*)&st, sizeof(*st)) < 0) { +80104fe0: 83 ec 04 sub $0x4,%esp +80104fe3: 6a 14 push $0x14 +80104fe5: 53 push %ebx +80104fe6: 6a 01 push $0x1 +80104fe8: e8 e3 fa ff ff call 80104ad0 +80104fed: 83 c4 10 add $0x10,%esp +80104ff0: 85 c0 test %eax,%eax +80104ff2: 78 1c js 80105010 + return filestat(f, st); +80104ff4: 83 ec 08 sub $0x8,%esp +80104ff7: ff 75 f4 push -0xc(%ebp) +80104ffa: 56 push %esi +80104ffb: e8 f0 c0 ff ff call 801010f0 +80105000: 83 c4 10 add $0x10,%esp +} +80105003: 8d 65 f8 lea -0x8(%ebp),%esp +80105006: 5b pop %ebx +80105007: 5e pop %esi +80105008: 5d pop %ebp +80105009: c3 ret +8010500a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + return -1; +80105010: b8 ff ff ff ff mov $0xffffffff,%eax +80105015: eb ec jmp 80105003 +80105017: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010501e: 66 90 xchg %ax,%ax + +80105020 : +void cleanupsyslink(struct inode * ip) { +80105020: 55 push %ebp +80105021: 89 e5 mov %esp,%ebp +80105023: 53 push %ebx +80105024: 83 ec 10 sub $0x10,%esp +80105027: 8b 5d 08 mov 0x8(%ebp),%ebx + ilock(ip); +8010502a: 53 push %ebx +8010502b: e8 70 c8 ff ff call 801018a0 + ip->nlink--; +80105030: 66 83 6b 56 01 subw $0x1,0x56(%ebx) + iupdate(ip); +80105035: 89 1c 24 mov %ebx,(%esp) +80105038: e8 b3 c7 ff ff call 801017f0 + iunlockput(ip); +8010503d: 89 1c 24 mov %ebx,(%esp) +80105040: e8 eb ca ff ff call 80101b30 +} +80105045: 8b 5d fc mov -0x4(%ebp),%ebx + end_op(); +80105048: 83 c4 10 add $0x10,%esp +} +8010504b: c9 leave + end_op(); +8010504c: e9 9f de ff ff jmp 80102ef0 +80105051: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105058: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010505f: 90 nop + +80105060 : +int sys_link(void) { +80105060: 55 push %ebp +80105061: 89 e5 mov %esp,%ebp +80105063: 57 push %edi +80105064: 56 push %esi + if (argstr(0, &old) < 0 || argstr(1, &new) < 0) { +80105065: 8d 45 d4 lea -0x2c(%ebp),%eax +int sys_link(void) { +80105068: 53 push %ebx +80105069: 83 ec 34 sub $0x34,%esp + if (argstr(0, &old) < 0 || argstr(1, &new) < 0) { +8010506c: 50 push %eax +8010506d: 6a 00 push $0x0 +8010506f: e8 cc fa ff ff call 80104b40 +80105074: 83 c4 10 add $0x10,%esp +80105077: 85 c0 test %eax,%eax +80105079: 0f 88 ff 00 00 00 js 8010517e +8010507f: 83 ec 08 sub $0x8,%esp +80105082: 8d 45 d0 lea -0x30(%ebp),%eax +80105085: 50 push %eax +80105086: 6a 01 push $0x1 +80105088: e8 b3 fa ff ff call 80104b40 +8010508d: 83 c4 10 add $0x10,%esp +80105090: 85 c0 test %eax,%eax +80105092: 0f 88 e6 00 00 00 js 8010517e + begin_op(); +80105098: e8 e3 dd ff ff call 80102e80 + if ((ip = namei(old)) == 0) { +8010509d: 83 ec 0c sub $0xc,%esp +801050a0: ff 75 d4 push -0x2c(%ebp) +801050a3: e8 18 d1 ff ff call 801021c0 +801050a8: 83 c4 10 add $0x10,%esp +801050ab: 89 c3 mov %eax,%ebx +801050ad: 85 c0 test %eax,%eax +801050af: 0f 84 e8 00 00 00 je 8010519d + ilock(ip); +801050b5: 83 ec 0c sub $0xc,%esp +801050b8: 50 push %eax +801050b9: e8 e2 c7 ff ff call 801018a0 + if (ip->type == T_DIR) { +801050be: 83 c4 10 add $0x10,%esp +801050c1: 66 83 7b 50 01 cmpw $0x1,0x50(%ebx) +801050c6: 0f 84 b9 00 00 00 je 80105185 + iupdate(ip); +801050cc: 83 ec 0c sub $0xc,%esp + ip->nlink++; +801050cf: 66 83 43 56 01 addw $0x1,0x56(%ebx) + if ((dp = nameiparent(new, name)) == 0) { +801050d4: 8d 7d da lea -0x26(%ebp),%edi + iupdate(ip); +801050d7: 53 push %ebx +801050d8: e8 13 c7 ff ff call 801017f0 + iunlock(ip); +801050dd: 89 1c 24 mov %ebx,(%esp) +801050e0: e8 9b c8 ff ff call 80101980 + if ((dp = nameiparent(new, name)) == 0) { +801050e5: 58 pop %eax +801050e6: 5a pop %edx +801050e7: 57 push %edi +801050e8: ff 75 d0 push -0x30(%ebp) +801050eb: e8 f0 d0 ff ff call 801021e0 +801050f0: 83 c4 10 add $0x10,%esp +801050f3: 89 c6 mov %eax,%esi +801050f5: 85 c0 test %eax,%eax +801050f7: 0f 84 ac 00 00 00 je 801051a9 + ilock(dp); +801050fd: 83 ec 0c sub $0xc,%esp +80105100: 50 push %eax +80105101: e8 9a c7 ff ff call 801018a0 + if (dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0) { +80105106: 8b 03 mov (%ebx),%eax +80105108: 83 c4 10 add $0x10,%esp +8010510b: 39 06 cmp %eax,(%esi) +8010510d: 75 41 jne 80105150 +8010510f: 83 ec 04 sub $0x4,%esp +80105112: ff 73 04 push 0x4(%ebx) +80105115: 57 push %edi +80105116: 56 push %esi +80105117: e8 e4 cf ff ff call 80102100 +8010511c: 83 c4 10 add $0x10,%esp +8010511f: 85 c0 test %eax,%eax +80105121: 78 2d js 80105150 + iunlockput(dp); +80105123: 83 ec 0c sub $0xc,%esp +80105126: 56 push %esi +80105127: e8 04 ca ff ff call 80101b30 + iput(ip); +8010512c: 89 1c 24 mov %ebx,(%esp) +8010512f: e8 9c c8 ff ff call 801019d0 + end_op(); +80105134: e8 b7 dd ff ff call 80102ef0 + return 0; +80105139: 83 c4 10 add $0x10,%esp +8010513c: 31 c0 xor %eax,%eax +} +8010513e: 8d 65 f4 lea -0xc(%ebp),%esp +80105141: 5b pop %ebx +80105142: 5e pop %esi +80105143: 5f pop %edi +80105144: 5d pop %ebp +80105145: c3 ret +80105146: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010514d: 8d 76 00 lea 0x0(%esi),%esi + iunlockput(dp); +80105150: 83 ec 0c sub $0xc,%esp +80105153: 56 push %esi +80105154: e8 d7 c9 ff ff call 80101b30 + ilock(ip); +80105159: 89 1c 24 mov %ebx,(%esp) +8010515c: e8 3f c7 ff ff call 801018a0 + ip->nlink--; +80105161: 66 83 6b 56 01 subw $0x1,0x56(%ebx) + iupdate(ip); +80105166: 89 1c 24 mov %ebx,(%esp) +80105169: e8 82 c6 ff ff call 801017f0 + iunlockput(ip); +8010516e: 89 1c 24 mov %ebx,(%esp) +80105171: e8 ba c9 ff ff call 80101b30 + end_op(); +80105176: e8 75 dd ff ff call 80102ef0 +} +8010517b: 83 c4 10 add $0x10,%esp + return -1; +8010517e: b8 ff ff ff ff mov $0xffffffff,%eax +} +80105183: eb b9 jmp 8010513e + iunlockput(ip); +80105185: 83 ec 0c sub $0xc,%esp +80105188: 53 push %ebx +80105189: e8 a2 c9 ff ff call 80101b30 + end_op(); +8010518e: e8 5d dd ff ff call 80102ef0 + return -1; +80105193: 83 c4 10 add $0x10,%esp +80105196: b8 ff ff ff ff mov $0xffffffff,%eax +8010519b: eb a1 jmp 8010513e + end_op(); +8010519d: e8 4e dd ff ff call 80102ef0 + return -1; +801051a2: b8 ff ff ff ff mov $0xffffffff,%eax +801051a7: eb 95 jmp 8010513e + ilock(ip); +801051a9: 83 ec 0c sub $0xc,%esp +801051ac: 53 push %ebx +801051ad: eb ad jmp 8010515c +801051af: 90 nop + +801051b0 : +int sys_unlink(void) { +801051b0: 55 push %ebp +801051b1: 89 e5 mov %esp,%ebp +801051b3: 57 push %edi +801051b4: 56 push %esi + if (argstr(0, &path) < 0) { +801051b5: 8d 45 c0 lea -0x40(%ebp),%eax +int sys_unlink(void) { +801051b8: 53 push %ebx +801051b9: 83 ec 54 sub $0x54,%esp + if (argstr(0, &path) < 0) { +801051bc: 50 push %eax +801051bd: 6a 00 push $0x0 +801051bf: e8 7c f9 ff ff call 80104b40 +801051c4: 83 c4 10 add $0x10,%esp +801051c7: 85 c0 test %eax,%eax +801051c9: 0f 88 4c 01 00 00 js 8010531b + begin_op(); +801051cf: e8 ac dc ff ff call 80102e80 + if ((dp = nameiparent(path, name)) == 0) { +801051d4: 8d 5d ca lea -0x36(%ebp),%ebx +801051d7: 83 ec 08 sub $0x8,%esp +801051da: 53 push %ebx +801051db: ff 75 c0 push -0x40(%ebp) +801051de: e8 fd cf ff ff call 801021e0 +801051e3: 83 c4 10 add $0x10,%esp +801051e6: 89 45 b4 mov %eax,-0x4c(%ebp) +801051e9: 85 c0 test %eax,%eax +801051eb: 0f 84 55 01 00 00 je 80105346 + ilock(dp); +801051f1: 83 ec 0c sub $0xc,%esp +801051f4: ff 75 b4 push -0x4c(%ebp) +801051f7: e8 a4 c6 ff ff call 801018a0 + if (namecmp(name, ".") == 0 || namecmp(name, "..") == 0) { +801051fc: 5a pop %edx +801051fd: 59 pop %ecx +801051fe: 68 20 7b 10 80 push $0x80107b20 +80105203: 53 push %ebx +80105204: e8 d7 cb ff ff call 80101de0 +80105209: 83 c4 10 add $0x10,%esp +8010520c: 85 c0 test %eax,%eax +8010520e: 0f 84 2d 01 00 00 je 80105341 +80105214: 83 ec 08 sub $0x8,%esp +80105217: 68 1f 7b 10 80 push $0x80107b1f +8010521c: 53 push %ebx +8010521d: e8 be cb ff ff call 80101de0 +80105222: 83 c4 10 add $0x10,%esp +80105225: 85 c0 test %eax,%eax +80105227: 0f 84 14 01 00 00 je 80105341 + if ((ip = dirlookup(dp, name, &off)) == 0) { +8010522d: 83 ec 04 sub $0x4,%esp +80105230: 8d 45 c4 lea -0x3c(%ebp),%eax +80105233: 50 push %eax +80105234: 53 push %ebx +80105235: ff 75 b4 push -0x4c(%ebp) +80105238: e8 c3 cb ff ff call 80101e00 +8010523d: 83 c4 10 add $0x10,%esp +80105240: 89 c3 mov %eax,%ebx +80105242: 85 c0 test %eax,%eax +80105244: 0f 84 f7 00 00 00 je 80105341 + ilock(ip); +8010524a: 83 ec 0c sub $0xc,%esp +8010524d: 50 push %eax +8010524e: e8 4d c6 ff ff call 801018a0 + if (ip->nlink < 1) { +80105253: 83 c4 10 add $0x10,%esp +80105256: 66 83 7b 56 00 cmpw $0x0,0x56(%ebx) +8010525b: 0f 8e 01 01 00 00 jle 80105362 + if (ip->type == T_DIR && !isdirempty(ip)) { +80105261: 66 83 7b 50 01 cmpw $0x1,0x50(%ebx) +80105266: 8d 7d d8 lea -0x28(%ebp),%edi +80105269: 74 65 je 801052d0 + memset(&de, 0, sizeof(de)); +8010526b: 83 ec 04 sub $0x4,%esp +8010526e: 6a 10 push $0x10 +80105270: 6a 00 push $0x0 +80105272: 57 push %edi +80105273: e8 48 f5 ff ff call 801047c0 + if (writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { +80105278: 6a 10 push $0x10 +8010527a: ff 75 c4 push -0x3c(%ebp) +8010527d: 57 push %edi +8010527e: ff 75 b4 push -0x4c(%ebp) +80105281: e8 2a ca ff ff call 80101cb0 +80105286: 83 c4 20 add $0x20,%esp +80105289: 83 f8 10 cmp $0x10,%eax +8010528c: 0f 85 dd 00 00 00 jne 8010536f + if (ip->type == T_DIR) { +80105292: 66 83 7b 50 01 cmpw $0x1,0x50(%ebx) +80105297: 0f 84 8b 00 00 00 je 80105328 + iunlockput(dp); +8010529d: 83 ec 0c sub $0xc,%esp +801052a0: ff 75 b4 push -0x4c(%ebp) +801052a3: e8 88 c8 ff ff call 80101b30 + ip->nlink--; +801052a8: 66 83 6b 56 01 subw $0x1,0x56(%ebx) + iupdate(ip); +801052ad: 89 1c 24 mov %ebx,(%esp) +801052b0: e8 3b c5 ff ff call 801017f0 + iunlockput(ip); +801052b5: 89 1c 24 mov %ebx,(%esp) +801052b8: e8 73 c8 ff ff call 80101b30 + end_op(); +801052bd: e8 2e dc ff ff call 80102ef0 + return 0; +801052c2: 83 c4 10 add $0x10,%esp +801052c5: 31 c0 xor %eax,%eax +} +801052c7: 8d 65 f4 lea -0xc(%ebp),%esp +801052ca: 5b pop %ebx +801052cb: 5e pop %esi +801052cc: 5f pop %edi +801052cd: 5d pop %ebp +801052ce: c3 ret +801052cf: 90 nop + for (off = 2 * sizeof(de); off < dp->size; off += sizeof(de)) { +801052d0: 83 7b 58 20 cmpl $0x20,0x58(%ebx) +801052d4: 76 95 jbe 8010526b +801052d6: be 20 00 00 00 mov $0x20,%esi +801052db: eb 0b jmp 801052e8 +801052dd: 8d 76 00 lea 0x0(%esi),%esi +801052e0: 83 c6 10 add $0x10,%esi +801052e3: 39 73 58 cmp %esi,0x58(%ebx) +801052e6: 76 83 jbe 8010526b + if (readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { +801052e8: 6a 10 push $0x10 +801052ea: 56 push %esi +801052eb: 57 push %edi +801052ec: 53 push %ebx +801052ed: e8 be c8 ff ff call 80101bb0 +801052f2: 83 c4 10 add $0x10,%esp +801052f5: 83 f8 10 cmp $0x10,%eax +801052f8: 75 5b jne 80105355 + if (de.inum != 0) { +801052fa: 66 83 7d d8 00 cmpw $0x0,-0x28(%ebp) +801052ff: 74 df je 801052e0 + iunlockput(ip); +80105301: 83 ec 0c sub $0xc,%esp +80105304: 53 push %ebx +80105305: e8 26 c8 ff ff call 80101b30 + iunlockput(dp); +8010530a: 58 pop %eax +8010530b: ff 75 b4 push -0x4c(%ebp) +8010530e: e8 1d c8 ff ff call 80101b30 + end_op(); +80105313: e8 d8 db ff ff call 80102ef0 + return -1; +80105318: 83 c4 10 add $0x10,%esp +8010531b: b8 ff ff ff ff mov $0xffffffff,%eax +80105320: eb a5 jmp 801052c7 +80105322: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + dp->nlink--; +80105328: 8b 45 b4 mov -0x4c(%ebp),%eax + iupdate(dp); +8010532b: 83 ec 0c sub $0xc,%esp + dp->nlink--; +8010532e: 66 83 68 56 01 subw $0x1,0x56(%eax) + iupdate(dp); +80105333: 50 push %eax +80105334: e8 b7 c4 ff ff call 801017f0 +80105339: 83 c4 10 add $0x10,%esp +8010533c: e9 5c ff ff ff jmp 8010529d + iunlockput(dp); +80105341: 83 ec 0c sub $0xc,%esp +80105344: eb c5 jmp 8010530b + end_op(); +80105346: e8 a5 db ff ff call 80102ef0 + return -1; +8010534b: b8 ff ff ff ff mov $0xffffffff,%eax +80105350: e9 72 ff ff ff jmp 801052c7 + panic("isdirempty: readi"); +80105355: 83 ec 0c sub $0xc,%esp +80105358: 68 44 7b 10 80 push $0x80107b44 +8010535d: e8 2e b0 ff ff call 80100390 + panic("unlink: nlink < 1"); +80105362: 83 ec 0c sub $0xc,%esp +80105365: 68 32 7b 10 80 push $0x80107b32 +8010536a: e8 21 b0 ff ff call 80100390 + panic("unlink: writei"); +8010536f: 83 ec 0c sub $0xc,%esp +80105372: 68 56 7b 10 80 push $0x80107b56 +80105377: e8 14 b0 ff ff call 80100390 +8010537c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80105380 : + +int sys_open(void) { +80105380: 55 push %ebp +80105381: 89 e5 mov %esp,%ebp +80105383: 57 push %edi +80105384: 56 push %esi + char *path; + int fd, omode; + struct file *f; + struct inode *ip; + + if (argstr(0, &path) < 0 || argint(1, &omode) < 0) { +80105385: 8d 45 e0 lea -0x20(%ebp),%eax +int sys_open(void) { +80105388: 53 push %ebx +80105389: 83 ec 24 sub $0x24,%esp + if (argstr(0, &path) < 0 || argint(1, &omode) < 0) { +8010538c: 50 push %eax +8010538d: 6a 00 push $0x0 +8010538f: e8 ac f7 ff ff call 80104b40 +80105394: 83 c4 10 add $0x10,%esp +80105397: 85 c0 test %eax,%eax +80105399: 0f 88 8e 00 00 00 js 8010542d +8010539f: 83 ec 08 sub $0x8,%esp +801053a2: 8d 45 e4 lea -0x1c(%ebp),%eax +801053a5: 50 push %eax +801053a6: 6a 01 push $0x1 +801053a8: e8 d3 f6 ff ff call 80104a80 +801053ad: 83 c4 10 add $0x10,%esp +801053b0: 85 c0 test %eax,%eax +801053b2: 78 79 js 8010542d + return -1; + } + + begin_op(); +801053b4: e8 c7 da ff ff call 80102e80 + + if (omode & O_CREATE) { +801053b9: f6 45 e5 02 testb $0x2,-0x1b(%ebp) +801053bd: 75 79 jne 80105438 + end_op(); + return -1; + } + } + else { + if ((ip = namei(path)) == 0) { +801053bf: 83 ec 0c sub $0xc,%esp +801053c2: ff 75 e0 push -0x20(%ebp) +801053c5: e8 f6 cd ff ff call 801021c0 +801053ca: 83 c4 10 add $0x10,%esp +801053cd: 89 c6 mov %eax,%esi +801053cf: 85 c0 test %eax,%eax +801053d1: 0f 84 7e 00 00 00 je 80105455 + end_op(); + return -1; + } + ilock(ip); +801053d7: 83 ec 0c sub $0xc,%esp +801053da: 50 push %eax +801053db: e8 c0 c4 ff ff call 801018a0 + if (ip->type == T_DIR && omode != O_RDONLY) { +801053e0: 83 c4 10 add $0x10,%esp +801053e3: 66 83 7e 50 01 cmpw $0x1,0x50(%esi) +801053e8: 0f 84 c2 00 00 00 je 801054b0 + end_op(); + return -1; + } + } + + if ((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0) { +801053ee: e8 5d bb ff ff call 80100f50 +801053f3: 89 c7 mov %eax,%edi +801053f5: 85 c0 test %eax,%eax +801053f7: 74 23 je 8010541c + struct proc *curproc = myproc(); +801053f9: e8 d2 e6 ff ff call 80103ad0 + for (fd = 0; fd < NOFILE; fd++) { +801053fe: 31 db xor %ebx,%ebx + if (curproc->ofile[fd] == 0) { +80105400: 8b 54 98 28 mov 0x28(%eax,%ebx,4),%edx +80105404: 85 d2 test %edx,%edx +80105406: 74 60 je 80105468 + for (fd = 0; fd < NOFILE; fd++) { +80105408: 83 c3 01 add $0x1,%ebx +8010540b: 83 fb 10 cmp $0x10,%ebx +8010540e: 75 f0 jne 80105400 + if (f) { + fileclose(f); +80105410: 83 ec 0c sub $0xc,%esp +80105413: 57 push %edi +80105414: e8 f7 bb ff ff call 80101010 +80105419: 83 c4 10 add $0x10,%esp + } + iunlockput(ip); +8010541c: 83 ec 0c sub $0xc,%esp +8010541f: 56 push %esi +80105420: e8 0b c7 ff ff call 80101b30 + end_op(); +80105425: e8 c6 da ff ff call 80102ef0 + return -1; +8010542a: 83 c4 10 add $0x10,%esp +8010542d: bb ff ff ff ff mov $0xffffffff,%ebx +80105432: eb 6d jmp 801054a1 +80105434: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + ip = create(path, T_FILE, 0, 0); +80105438: 83 ec 0c sub $0xc,%esp +8010543b: 8b 45 e0 mov -0x20(%ebp),%eax +8010543e: 31 c9 xor %ecx,%ecx +80105440: ba 02 00 00 00 mov $0x2,%edx +80105445: 6a 00 push $0x0 +80105447: e8 e4 f7 ff ff call 80104c30 + if (ip == 0) { +8010544c: 83 c4 10 add $0x10,%esp + ip = create(path, T_FILE, 0, 0); +8010544f: 89 c6 mov %eax,%esi + if (ip == 0) { +80105451: 85 c0 test %eax,%eax +80105453: 75 99 jne 801053ee + end_op(); +80105455: e8 96 da ff ff call 80102ef0 + return -1; +8010545a: bb ff ff ff ff mov $0xffffffff,%ebx +8010545f: eb 40 jmp 801054a1 +80105461: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + } + iunlock(ip); +80105468: 83 ec 0c sub $0xc,%esp + curproc->ofile[fd] = f; +8010546b: 89 7c 98 28 mov %edi,0x28(%eax,%ebx,4) + iunlock(ip); +8010546f: 56 push %esi +80105470: e8 0b c5 ff ff call 80101980 + end_op(); +80105475: e8 76 da ff ff call 80102ef0 + + f->type = FD_INODE; +8010547a: c7 07 02 00 00 00 movl $0x2,(%edi) + f->ip = ip; + f->off = 0; + f->readable = !(omode & O_WRONLY); +80105480: 8b 55 e4 mov -0x1c(%ebp),%edx + f->writable = (omode & O_WRONLY) || (omode & O_RDWR); +80105483: 83 c4 10 add $0x10,%esp + f->ip = ip; +80105486: 89 77 10 mov %esi,0x10(%edi) + f->readable = !(omode & O_WRONLY); +80105489: 89 d0 mov %edx,%eax + f->off = 0; +8010548b: c7 47 14 00 00 00 00 movl $0x0,0x14(%edi) + f->readable = !(omode & O_WRONLY); +80105492: f7 d0 not %eax +80105494: 83 e0 01 and $0x1,%eax + f->writable = (omode & O_WRONLY) || (omode & O_RDWR); +80105497: 83 e2 03 and $0x3,%edx + f->readable = !(omode & O_WRONLY); +8010549a: 88 47 08 mov %al,0x8(%edi) + f->writable = (omode & O_WRONLY) || (omode & O_RDWR); +8010549d: 0f 95 47 09 setne 0x9(%edi) + return fd; +} +801054a1: 8d 65 f4 lea -0xc(%ebp),%esp +801054a4: 89 d8 mov %ebx,%eax +801054a6: 5b pop %ebx +801054a7: 5e pop %esi +801054a8: 5f pop %edi +801054a9: 5d pop %ebp +801054aa: c3 ret +801054ab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801054af: 90 nop + if (ip->type == T_DIR && omode != O_RDONLY) { +801054b0: 8b 4d e4 mov -0x1c(%ebp),%ecx +801054b3: 85 c9 test %ecx,%ecx +801054b5: 0f 84 33 ff ff ff je 801053ee +801054bb: e9 5c ff ff ff jmp 8010541c + +801054c0 : + +int sys_mkdir(void) { +801054c0: 55 push %ebp +801054c1: 89 e5 mov %esp,%ebp +801054c3: 83 ec 18 sub $0x18,%esp + char *path; + struct inode *ip; + + begin_op(); +801054c6: e8 b5 d9 ff ff call 80102e80 + if (argstr(0, &path) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0) { +801054cb: 83 ec 08 sub $0x8,%esp +801054ce: 8d 45 f4 lea -0xc(%ebp),%eax +801054d1: 50 push %eax +801054d2: 6a 00 push $0x0 +801054d4: e8 67 f6 ff ff call 80104b40 +801054d9: 83 c4 10 add $0x10,%esp +801054dc: 85 c0 test %eax,%eax +801054de: 78 30 js 80105510 +801054e0: 83 ec 0c sub $0xc,%esp +801054e3: 8b 45 f4 mov -0xc(%ebp),%eax +801054e6: 31 c9 xor %ecx,%ecx +801054e8: ba 01 00 00 00 mov $0x1,%edx +801054ed: 6a 00 push $0x0 +801054ef: e8 3c f7 ff ff call 80104c30 +801054f4: 83 c4 10 add $0x10,%esp +801054f7: 85 c0 test %eax,%eax +801054f9: 74 15 je 80105510 + end_op(); + return -1; + } + iunlockput(ip); +801054fb: 83 ec 0c sub $0xc,%esp +801054fe: 50 push %eax +801054ff: e8 2c c6 ff ff call 80101b30 + end_op(); +80105504: e8 e7 d9 ff ff call 80102ef0 + return 0; +80105509: 83 c4 10 add $0x10,%esp +8010550c: 31 c0 xor %eax,%eax +} +8010550e: c9 leave +8010550f: c3 ret + end_op(); +80105510: e8 db d9 ff ff call 80102ef0 + return -1; +80105515: b8 ff ff ff ff mov $0xffffffff,%eax +} +8010551a: c9 leave +8010551b: c3 ret +8010551c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80105520 : + +int sys_mknod(void) { +80105520: 55 push %ebp +80105521: 89 e5 mov %esp,%ebp +80105523: 83 ec 18 sub $0x18,%esp + struct inode *ip; + char *path; + int major, minor; + + begin_op(); +80105526: e8 55 d9 ff ff call 80102e80 + if ((argstr(0, &path)) < 0 || +8010552b: 83 ec 08 sub $0x8,%esp +8010552e: 8d 45 ec lea -0x14(%ebp),%eax +80105531: 50 push %eax +80105532: 6a 00 push $0x0 +80105534: e8 07 f6 ff ff call 80104b40 +80105539: 83 c4 10 add $0x10,%esp +8010553c: 85 c0 test %eax,%eax +8010553e: 78 60 js 801055a0 + argint(1, &major) < 0 || +80105540: 83 ec 08 sub $0x8,%esp +80105543: 8d 45 f0 lea -0x10(%ebp),%eax +80105546: 50 push %eax +80105547: 6a 01 push $0x1 +80105549: e8 32 f5 ff ff call 80104a80 + if ((argstr(0, &path)) < 0 || +8010554e: 83 c4 10 add $0x10,%esp +80105551: 85 c0 test %eax,%eax +80105553: 78 4b js 801055a0 + argint(2, &minor) < 0 || +80105555: 83 ec 08 sub $0x8,%esp +80105558: 8d 45 f4 lea -0xc(%ebp),%eax +8010555b: 50 push %eax +8010555c: 6a 02 push $0x2 +8010555e: e8 1d f5 ff ff call 80104a80 + argint(1, &major) < 0 || +80105563: 83 c4 10 add $0x10,%esp +80105566: 85 c0 test %eax,%eax +80105568: 78 36 js 801055a0 + (ip = create(path, T_DEV, major, minor)) == 0) { +8010556a: 0f bf 45 f4 movswl -0xc(%ebp),%eax +8010556e: 83 ec 0c sub $0xc,%esp +80105571: 0f bf 4d f0 movswl -0x10(%ebp),%ecx +80105575: ba 03 00 00 00 mov $0x3,%edx +8010557a: 50 push %eax +8010557b: 8b 45 ec mov -0x14(%ebp),%eax +8010557e: e8 ad f6 ff ff call 80104c30 + argint(2, &minor) < 0 || +80105583: 83 c4 10 add $0x10,%esp +80105586: 85 c0 test %eax,%eax +80105588: 74 16 je 801055a0 + end_op(); + return -1; + } + iunlockput(ip); +8010558a: 83 ec 0c sub $0xc,%esp +8010558d: 50 push %eax +8010558e: e8 9d c5 ff ff call 80101b30 + end_op(); +80105593: e8 58 d9 ff ff call 80102ef0 + return 0; +80105598: 83 c4 10 add $0x10,%esp +8010559b: 31 c0 xor %eax,%eax +} +8010559d: c9 leave +8010559e: c3 ret +8010559f: 90 nop + end_op(); +801055a0: e8 4b d9 ff ff call 80102ef0 + return -1; +801055a5: b8 ff ff ff ff mov $0xffffffff,%eax +} +801055aa: c9 leave +801055ab: c3 ret +801055ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +801055b0 : + +int sys_chdir(void) { +801055b0: 55 push %ebp +801055b1: 89 e5 mov %esp,%ebp +801055b3: 56 push %esi +801055b4: 53 push %ebx +801055b5: 83 ec 10 sub $0x10,%esp + char *path; + struct inode *ip; + struct proc *curproc = myproc(); +801055b8: e8 13 e5 ff ff call 80103ad0 +801055bd: 89 c6 mov %eax,%esi + + begin_op(); +801055bf: e8 bc d8 ff ff call 80102e80 + if (argstr(0, &path) < 0 || (ip = namei(path)) == 0) { +801055c4: 83 ec 08 sub $0x8,%esp +801055c7: 8d 45 f4 lea -0xc(%ebp),%eax +801055ca: 50 push %eax +801055cb: 6a 00 push $0x0 +801055cd: e8 6e f5 ff ff call 80104b40 +801055d2: 83 c4 10 add $0x10,%esp +801055d5: 85 c0 test %eax,%eax +801055d7: 78 77 js 80105650 +801055d9: 83 ec 0c sub $0xc,%esp +801055dc: ff 75 f4 push -0xc(%ebp) +801055df: e8 dc cb ff ff call 801021c0 +801055e4: 83 c4 10 add $0x10,%esp +801055e7: 89 c3 mov %eax,%ebx +801055e9: 85 c0 test %eax,%eax +801055eb: 74 63 je 80105650 + end_op(); + return -1; + } + ilock(ip); +801055ed: 83 ec 0c sub $0xc,%esp +801055f0: 50 push %eax +801055f1: e8 aa c2 ff ff call 801018a0 + if (ip->type != T_DIR) { +801055f6: 83 c4 10 add $0x10,%esp +801055f9: 66 83 7b 50 01 cmpw $0x1,0x50(%ebx) +801055fe: 75 30 jne 80105630 + iunlockput(ip); + end_op(); + return -1; + } + iunlock(ip); +80105600: 83 ec 0c sub $0xc,%esp +80105603: 53 push %ebx +80105604: e8 77 c3 ff ff call 80101980 + iput(curproc->cwd); +80105609: 58 pop %eax +8010560a: ff 76 68 push 0x68(%esi) +8010560d: e8 be c3 ff ff call 801019d0 + end_op(); +80105612: e8 d9 d8 ff ff call 80102ef0 + curproc->cwd = ip; +80105617: 89 5e 68 mov %ebx,0x68(%esi) + return 0; +8010561a: 83 c4 10 add $0x10,%esp +8010561d: 31 c0 xor %eax,%eax +} +8010561f: 8d 65 f8 lea -0x8(%ebp),%esp +80105622: 5b pop %ebx +80105623: 5e pop %esi +80105624: 5d pop %ebp +80105625: c3 ret +80105626: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010562d: 8d 76 00 lea 0x0(%esi),%esi + iunlockput(ip); +80105630: 83 ec 0c sub $0xc,%esp +80105633: 53 push %ebx +80105634: e8 f7 c4 ff ff call 80101b30 + end_op(); +80105639: e8 b2 d8 ff ff call 80102ef0 + return -1; +8010563e: 83 c4 10 add $0x10,%esp +80105641: b8 ff ff ff ff mov $0xffffffff,%eax +80105646: eb d7 jmp 8010561f +80105648: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010564f: 90 nop + end_op(); +80105650: e8 9b d8 ff ff call 80102ef0 + return -1; +80105655: b8 ff ff ff ff mov $0xffffffff,%eax +8010565a: eb c3 jmp 8010561f +8010565c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80105660 : + +int sys_exec(void) { +80105660: 55 push %ebp +80105661: 89 e5 mov %esp,%ebp +80105663: 57 push %edi +80105664: 56 push %esi + char *path, *argv[MAXARG]; + int i; + uint uargv, uarg; + + if (argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0) { +80105665: 8d 85 5c ff ff ff lea -0xa4(%ebp),%eax +int sys_exec(void) { +8010566b: 53 push %ebx +8010566c: 81 ec a4 00 00 00 sub $0xa4,%esp + if (argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0) { +80105672: 50 push %eax +80105673: 6a 00 push $0x0 +80105675: e8 c6 f4 ff ff call 80104b40 +8010567a: 83 c4 10 add $0x10,%esp +8010567d: 85 c0 test %eax,%eax +8010567f: 0f 88 87 00 00 00 js 8010570c +80105685: 83 ec 08 sub $0x8,%esp +80105688: 8d 85 60 ff ff ff lea -0xa0(%ebp),%eax +8010568e: 50 push %eax +8010568f: 6a 01 push $0x1 +80105691: e8 ea f3 ff ff call 80104a80 +80105696: 83 c4 10 add $0x10,%esp +80105699: 85 c0 test %eax,%eax +8010569b: 78 6f js 8010570c + return -1; + } + memset(argv, 0, sizeof(argv)); +8010569d: 83 ec 04 sub $0x4,%esp +801056a0: 8d b5 68 ff ff ff lea -0x98(%ebp),%esi + for (i = 0;; i++) { +801056a6: 31 db xor %ebx,%ebx + memset(argv, 0, sizeof(argv)); +801056a8: 68 80 00 00 00 push $0x80 +801056ad: 6a 00 push $0x0 +801056af: 56 push %esi +801056b0: e8 0b f1 ff ff call 801047c0 +801056b5: 83 c4 10 add $0x10,%esp +801056b8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801056bf: 90 nop + if (i >= NELEM(argv)) { + return -1; + } + if (fetchint(uargv + 4 * i, (int*)&uarg) < 0) { +801056c0: 83 ec 08 sub $0x8,%esp +801056c3: 8d 85 64 ff ff ff lea -0x9c(%ebp),%eax +801056c9: 8d 3c 9d 00 00 00 00 lea 0x0(,%ebx,4),%edi +801056d0: 50 push %eax +801056d1: 8b 85 60 ff ff ff mov -0xa0(%ebp),%eax +801056d7: 01 f8 add %edi,%eax +801056d9: 50 push %eax +801056da: e8 11 f3 ff ff call 801049f0 +801056df: 83 c4 10 add $0x10,%esp +801056e2: 85 c0 test %eax,%eax +801056e4: 78 26 js 8010570c + return -1; + } + if (uarg == 0) { +801056e6: 8b 85 64 ff ff ff mov -0x9c(%ebp),%eax +801056ec: 85 c0 test %eax,%eax +801056ee: 74 30 je 80105720 + argv[i] = 0; + break; + } + if (fetchstr(uarg, &argv[i]) < 0) { +801056f0: 83 ec 08 sub $0x8,%esp +801056f3: 8d 14 3e lea (%esi,%edi,1),%edx +801056f6: 52 push %edx +801056f7: 50 push %eax +801056f8: e8 33 f3 ff ff call 80104a30 +801056fd: 83 c4 10 add $0x10,%esp +80105700: 85 c0 test %eax,%eax +80105702: 78 08 js 8010570c + for (i = 0;; i++) { +80105704: 83 c3 01 add $0x1,%ebx + if (i >= NELEM(argv)) { +80105707: 83 fb 20 cmp $0x20,%ebx +8010570a: 75 b4 jne 801056c0 + return -1; + } + } + return exec(path, argv); +} +8010570c: 8d 65 f4 lea -0xc(%ebp),%esp + return -1; +8010570f: b8 ff ff ff ff mov $0xffffffff,%eax +} +80105714: 5b pop %ebx +80105715: 5e pop %esi +80105716: 5f pop %edi +80105717: 5d pop %ebp +80105718: c3 ret +80105719: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + argv[i] = 0; +80105720: c7 84 9d 68 ff ff ff movl $0x0,-0x98(%ebp,%ebx,4) +80105727: 00 00 00 00 + return exec(path, argv); +8010572b: 83 ec 08 sub $0x8,%esp +8010572e: 56 push %esi +8010572f: ff b5 5c ff ff ff push -0xa4(%ebp) +80105735: e8 36 b4 ff ff call 80100b70 +8010573a: 83 c4 10 add $0x10,%esp +} +8010573d: 8d 65 f4 lea -0xc(%ebp),%esp +80105740: 5b pop %ebx +80105741: 5e pop %esi +80105742: 5f pop %edi +80105743: 5d pop %ebp +80105744: c3 ret +80105745: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010574c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80105750 : + +int sys_pipe(void) { +80105750: 55 push %ebp +80105751: 89 e5 mov %esp,%ebp +80105753: 57 push %edi +80105754: 56 push %esi + int *fd; + struct file *rf, *wf; + int fd0, fd1; + + if (argptr(0, (void*)&fd, 2 * sizeof(fd[0])) < 0) { +80105755: 8d 45 dc lea -0x24(%ebp),%eax +int sys_pipe(void) { +80105758: 53 push %ebx +80105759: 83 ec 20 sub $0x20,%esp + if (argptr(0, (void*)&fd, 2 * sizeof(fd[0])) < 0) { +8010575c: 6a 08 push $0x8 +8010575e: 50 push %eax +8010575f: 6a 00 push $0x0 +80105761: e8 6a f3 ff ff call 80104ad0 +80105766: 83 c4 10 add $0x10,%esp +80105769: 85 c0 test %eax,%eax +8010576b: 78 4a js 801057b7 + return -1; + } + if (pipealloc(&rf, &wf) < 0) { +8010576d: 83 ec 08 sub $0x8,%esp +80105770: 8d 45 e4 lea -0x1c(%ebp),%eax +80105773: 50 push %eax +80105774: 8d 45 e0 lea -0x20(%ebp),%eax +80105777: 50 push %eax +80105778: e8 23 de ff ff call 801035a0 +8010577d: 83 c4 10 add $0x10,%esp +80105780: 85 c0 test %eax,%eax +80105782: 78 33 js 801057b7 + return -1; + } + fd0 = -1; + if ((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0) { +80105784: 8b 7d e0 mov -0x20(%ebp),%edi + for (fd = 0; fd < NOFILE; fd++) { +80105787: 31 db xor %ebx,%ebx + struct proc *curproc = myproc(); +80105789: e8 42 e3 ff ff call 80103ad0 + for (fd = 0; fd < NOFILE; fd++) { +8010578e: 66 90 xchg %ax,%ax + if (curproc->ofile[fd] == 0) { +80105790: 8b 74 98 28 mov 0x28(%eax,%ebx,4),%esi +80105794: 85 f6 test %esi,%esi +80105796: 74 28 je 801057c0 + for (fd = 0; fd < NOFILE; fd++) { +80105798: 83 c3 01 add $0x1,%ebx +8010579b: 83 fb 10 cmp $0x10,%ebx +8010579e: 75 f0 jne 80105790 + if (fd0 >= 0) { + myproc()->ofile[fd0] = 0; + } + fileclose(rf); +801057a0: 83 ec 0c sub $0xc,%esp +801057a3: ff 75 e0 push -0x20(%ebp) +801057a6: e8 65 b8 ff ff call 80101010 + fileclose(wf); +801057ab: 58 pop %eax +801057ac: ff 75 e4 push -0x1c(%ebp) +801057af: e8 5c b8 ff ff call 80101010 + return -1; +801057b4: 83 c4 10 add $0x10,%esp +801057b7: b8 ff ff ff ff mov $0xffffffff,%eax +801057bc: eb 53 jmp 80105811 +801057be: 66 90 xchg %ax,%ax + curproc->ofile[fd] = f; +801057c0: 8d 73 08 lea 0x8(%ebx),%esi +801057c3: 89 7c b0 08 mov %edi,0x8(%eax,%esi,4) + if ((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0) { +801057c7: 8b 7d e4 mov -0x1c(%ebp),%edi + struct proc *curproc = myproc(); +801057ca: e8 01 e3 ff ff call 80103ad0 + for (fd = 0; fd < NOFILE; fd++) { +801057cf: 31 d2 xor %edx,%edx +801057d1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + if (curproc->ofile[fd] == 0) { +801057d8: 8b 4c 90 28 mov 0x28(%eax,%edx,4),%ecx +801057dc: 85 c9 test %ecx,%ecx +801057de: 74 20 je 80105800 + for (fd = 0; fd < NOFILE; fd++) { +801057e0: 83 c2 01 add $0x1,%edx +801057e3: 83 fa 10 cmp $0x10,%edx +801057e6: 75 f0 jne 801057d8 + myproc()->ofile[fd0] = 0; +801057e8: e8 e3 e2 ff ff call 80103ad0 +801057ed: c7 44 b0 08 00 00 00 movl $0x0,0x8(%eax,%esi,4) +801057f4: 00 +801057f5: eb a9 jmp 801057a0 +801057f7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801057fe: 66 90 xchg %ax,%ax + curproc->ofile[fd] = f; +80105800: 89 7c 90 28 mov %edi,0x28(%eax,%edx,4) + } + fd[0] = fd0; +80105804: 8b 45 dc mov -0x24(%ebp),%eax +80105807: 89 18 mov %ebx,(%eax) + fd[1] = fd1; +80105809: 8b 45 dc mov -0x24(%ebp),%eax +8010580c: 89 50 04 mov %edx,0x4(%eax) + return 0; +8010580f: 31 c0 xor %eax,%eax +} +80105811: 8d 65 f4 lea -0xc(%ebp),%esp +80105814: 5b pop %ebx +80105815: 5e pop %esi +80105816: 5f pop %edi +80105817: 5d pop %ebp +80105818: c3 ret +80105819: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80105820 : + +int sys_getch(void) { + return consoleget(); +80105820: e9 6b b0 ff ff jmp 80100890 +80105825: 66 90 xchg %ax,%ax +80105827: 66 90 xchg %ax,%ax +80105829: 66 90 xchg %ax,%ax +8010582b: 66 90 xchg %ax,%ax +8010582d: 66 90 xchg %ax,%ax +8010582f: 90 nop + +80105830 : +#include "mmu.h" +#include "proc.h" + +int sys_fork(void) +{ + return fork(); +80105830: e9 3b e4 ff ff jmp 80103c70 +80105835: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010583c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80105840 : +} + +int sys_exit(void) +{ +80105840: 55 push %ebp +80105841: 89 e5 mov %esp,%ebp +80105843: 83 ec 08 sub $0x8,%esp + exit(); +80105846: e8 a5 e6 ff ff call 80103ef0 + return 0; // not reached +} +8010584b: 31 c0 xor %eax,%eax +8010584d: c9 leave +8010584e: c3 ret +8010584f: 90 nop + +80105850 : + +int sys_wait(void) +{ + return wait(); +80105850: e9 cb e7 ff ff jmp 80104020 +80105855: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010585c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80105860 : +} + +int sys_kill(void) +{ +80105860: 55 push %ebp +80105861: 89 e5 mov %esp,%ebp +80105863: 83 ec 20 sub $0x20,%esp + int pid; + + if (argint(0, &pid) < 0) +80105866: 8d 45 f4 lea -0xc(%ebp),%eax +80105869: 50 push %eax +8010586a: 6a 00 push $0x0 +8010586c: e8 0f f2 ff ff call 80104a80 +80105871: 83 c4 10 add $0x10,%esp +80105874: 85 c0 test %eax,%eax +80105876: 78 18 js 80105890 + { + return -1; + } + return kill(pid); +80105878: 83 ec 0c sub $0xc,%esp +8010587b: ff 75 f4 push -0xc(%ebp) +8010587e: e8 3d ea ff ff call 801042c0 +80105883: 83 c4 10 add $0x10,%esp +} +80105886: c9 leave +80105887: c3 ret +80105888: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010588f: 90 nop +80105890: c9 leave + return -1; +80105891: b8 ff ff ff ff mov $0xffffffff,%eax +} +80105896: c3 ret +80105897: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010589e: 66 90 xchg %ax,%ax + +801058a0 : + +int sys_getpid(void) +{ +801058a0: 55 push %ebp +801058a1: 89 e5 mov %esp,%ebp +801058a3: 83 ec 08 sub $0x8,%esp + return myproc()->pid; +801058a6: e8 25 e2 ff ff call 80103ad0 +801058ab: 8b 40 10 mov 0x10(%eax),%eax +} +801058ae: c9 leave +801058af: c3 ret + +801058b0 : + +int sys_sbrk(void) +{ +801058b0: 55 push %ebp +801058b1: 89 e5 mov %esp,%ebp +801058b3: 53 push %ebx + int addr; + int n; + + if (argint(0, &n) < 0) +801058b4: 8d 45 f4 lea -0xc(%ebp),%eax +{ +801058b7: 83 ec 1c sub $0x1c,%esp + if (argint(0, &n) < 0) +801058ba: 50 push %eax +801058bb: 6a 00 push $0x0 +801058bd: e8 be f1 ff ff call 80104a80 +801058c2: 83 c4 10 add $0x10,%esp +801058c5: 85 c0 test %eax,%eax +801058c7: 78 27 js 801058f0 + { + return -1; + } + addr = myproc()->sz; +801058c9: e8 02 e2 ff ff call 80103ad0 + if (growproc(n) < 0) +801058ce: 83 ec 0c sub $0xc,%esp + addr = myproc()->sz; +801058d1: 8b 18 mov (%eax),%ebx + if (growproc(n) < 0) +801058d3: ff 75 f4 push -0xc(%ebp) +801058d6: e8 15 e3 ff ff call 80103bf0 +801058db: 83 c4 10 add $0x10,%esp +801058de: 85 c0 test %eax,%eax +801058e0: 78 0e js 801058f0 + { + return -1; + } + return addr; +} +801058e2: 89 d8 mov %ebx,%eax +801058e4: 8b 5d fc mov -0x4(%ebp),%ebx +801058e7: c9 leave +801058e8: c3 ret +801058e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return -1; +801058f0: bb ff ff ff ff mov $0xffffffff,%ebx +801058f5: eb eb jmp 801058e2 +801058f7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801058fe: 66 90 xchg %ax,%ax + +80105900 : + +int sys_sleep(void) +{ +80105900: 55 push %ebp +80105901: 89 e5 mov %esp,%ebp +80105903: 53 push %ebx + int n; + uint ticks0; + + if (argint(0, &n) < 0) +80105904: 8d 45 f4 lea -0xc(%ebp),%eax +{ +80105907: 83 ec 1c sub $0x1c,%esp + if (argint(0, &n) < 0) +8010590a: 50 push %eax +8010590b: 6a 00 push $0x0 +8010590d: e8 6e f1 ff ff call 80104a80 +80105912: 83 c4 10 add $0x10,%esp +80105915: 85 c0 test %eax,%eax +80105917: 0f 88 8a 00 00 00 js 801059a7 + { + return -1; + } + acquire(&tickslock); +8010591d: 83 ec 0c sub $0xc,%esp +80105920: 68 a0 3c 11 80 push $0x80113ca0 +80105925: e8 d6 ed ff ff call 80104700 + ticks0 = ticks; + while (ticks - ticks0 < n) +8010592a: 8b 55 f4 mov -0xc(%ebp),%edx + ticks0 = ticks; +8010592d: 8b 1d 80 3c 11 80 mov 0x80113c80,%ebx + while (ticks - ticks0 < n) +80105933: 83 c4 10 add $0x10,%esp +80105936: 85 d2 test %edx,%edx +80105938: 75 27 jne 80105961 +8010593a: eb 54 jmp 80105990 +8010593c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (myproc()->killed) + { + release(&tickslock); + return -1; + } + sleep(&ticks, &tickslock); +80105940: 83 ec 08 sub $0x8,%esp +80105943: 68 a0 3c 11 80 push $0x80113ca0 +80105948: 68 80 3c 11 80 push $0x80113c80 +8010594d: e8 4e e8 ff ff call 801041a0 + while (ticks - ticks0 < n) +80105952: a1 80 3c 11 80 mov 0x80113c80,%eax +80105957: 83 c4 10 add $0x10,%esp +8010595a: 29 d8 sub %ebx,%eax +8010595c: 3b 45 f4 cmp -0xc(%ebp),%eax +8010595f: 73 2f jae 80105990 + if (myproc()->killed) +80105961: e8 6a e1 ff ff call 80103ad0 +80105966: 8b 40 24 mov 0x24(%eax),%eax +80105969: 85 c0 test %eax,%eax +8010596b: 74 d3 je 80105940 + release(&tickslock); +8010596d: 83 ec 0c sub $0xc,%esp +80105970: 68 a0 3c 11 80 push $0x80113ca0 +80105975: e8 26 ed ff ff call 801046a0 + } + release(&tickslock); + return 0; +} +8010597a: 8b 5d fc mov -0x4(%ebp),%ebx + return -1; +8010597d: 83 c4 10 add $0x10,%esp +80105980: b8 ff ff ff ff mov $0xffffffff,%eax +} +80105985: c9 leave +80105986: c3 ret +80105987: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010598e: 66 90 xchg %ax,%ax + release(&tickslock); +80105990: 83 ec 0c sub $0xc,%esp +80105993: 68 a0 3c 11 80 push $0x80113ca0 +80105998: e8 03 ed ff ff call 801046a0 + return 0; +8010599d: 83 c4 10 add $0x10,%esp +801059a0: 31 c0 xor %eax,%eax +} +801059a2: 8b 5d fc mov -0x4(%ebp),%ebx +801059a5: c9 leave +801059a6: c3 ret + return -1; +801059a7: b8 ff ff ff ff mov $0xffffffff,%eax +801059ac: eb f4 jmp 801059a2 +801059ae: 66 90 xchg %ax,%ax + +801059b0 : + +// return how many clock tick interrupts have occurred +// since start. +int sys_uptime(void) +{ +801059b0: 55 push %ebp +801059b1: 89 e5 mov %esp,%ebp +801059b3: 53 push %ebx +801059b4: 83 ec 10 sub $0x10,%esp + uint xticks; + + acquire(&tickslock); +801059b7: 68 a0 3c 11 80 push $0x80113ca0 +801059bc: e8 3f ed ff ff call 80104700 + xticks = ticks; +801059c1: 8b 1d 80 3c 11 80 mov 0x80113c80,%ebx + release(&tickslock); +801059c7: c7 04 24 a0 3c 11 80 movl $0x80113ca0,(%esp) +801059ce: e8 cd ec ff ff call 801046a0 + return xticks; +} +801059d3: 89 d8 mov %ebx,%eax +801059d5: 8b 5d fc mov -0x4(%ebp),%ebx +801059d8: c9 leave +801059d9: c3 ret +801059da: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +801059e0 : + +int sys_greeting(void) +{ +801059e0: 55 push %ebp +801059e1: 89 e5 mov %esp,%ebp +801059e3: 83 ec 14 sub $0x14,%esp + cprintf("Hello again\n"); +801059e6: 68 65 7b 10 80 push $0x80107b65 +801059eb: e8 c0 ac ff ff call 801006b0 + return 0; +} +801059f0: 31 c0 xor %eax,%eax +801059f2: c9 leave +801059f3: c3 ret +801059f4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801059fb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801059ff: 90 nop + +80105a00 : + +int sys_shutdown(void) +{ +80105a00: 55 push %ebp +80105a01: 89 e5 mov %esp,%ebp +80105a03: 83 ec 20 sub $0x20,%esp + int restart; + if (argint(0, &restart) < 0) +80105a06: 8d 45 f4 lea -0xc(%ebp),%eax +80105a09: 50 push %eax +80105a0a: 6a 00 push $0x0 +80105a0c: e8 6f f0 ff ff call 80104a80 +80105a11: 83 c4 10 add $0x10,%esp +80105a14: 85 c0 test %eax,%eax +80105a16: 78 2f js 80105a47 + { + return -1; + } + + if (restart == 1) +80105a18: 83 7d f4 01 cmpl $0x1,-0xc(%ebp) +80105a1c: 74 12 je 80105a30 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80105a1e: b8 00 20 00 00 mov $0x2000,%eax +80105a23: ba 04 06 00 00 mov $0x604,%edx +80105a28: 66 ef out %ax,(%dx) + else + { + outw(0x604, 0x2000); + } + return 0; +80105a2a: c9 leave + return 0; +80105a2b: 31 c0 xor %eax,%eax +80105a2d: c3 ret +80105a2e: 66 90 xchg %ax,%ax + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80105a30: ba 64 00 00 00 mov $0x64,%edx +80105a35: 8d 76 00 lea 0x0(%esi),%esi +80105a38: ec in (%dx),%al + while (good & 0x02) { +80105a39: a8 02 test $0x2,%al +80105a3b: 75 fb jne 80105a38 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80105a3d: b8 fe ff ff ff mov $0xfffffffe,%eax +80105a42: ee out %al,(%dx) +80105a43: c9 leave + return 0; +80105a44: 31 c0 xor %eax,%eax +80105a46: c3 ret +80105a47: c9 leave + return -1; +80105a48: b8 ff ff ff ff mov $0xffffffff,%eax +80105a4d: c3 ret + +80105a4e : + + # vectors.S sends all traps here. +.globl alltraps +alltraps: + # Build trap frame. + pushl %ds +80105a4e: 1e push %ds + pushl %es +80105a4f: 06 push %es + pushl %fs +80105a50: 0f a0 push %fs + pushl %gs +80105a52: 0f a8 push %gs + pushal +80105a54: 60 pusha + + # Set up data segments. + movw $(SEG_KDATA<<3), %ax +80105a55: 66 b8 10 00 mov $0x10,%ax + movw %ax, %ds +80105a59: 8e d8 mov %eax,%ds + movw %ax, %es +80105a5b: 8e c0 mov %eax,%es + + # Call trap(tf), where tf=%esp + pushl %esp +80105a5d: 54 push %esp + call trap +80105a5e: e8 cd 00 00 00 call 80105b30 + addl $4, %esp +80105a63: 83 c4 04 add $0x4,%esp + +80105a66 : + + # Return falls through to trapret... +.globl trapret +trapret: + popal +80105a66: 61 popa + popl %gs +80105a67: 0f a9 pop %gs + popl %fs +80105a69: 0f a1 pop %fs + popl %es +80105a6b: 07 pop %es + popl %ds +80105a6c: 1f pop %ds + addl $0x8, %esp # trapno and errcode +80105a6d: 83 c4 08 add $0x8,%esp + iret +80105a70: cf iret +80105a71: 66 90 xchg %ax,%ax +80105a73: 66 90 xchg %ax,%ax +80105a75: 66 90 xchg %ax,%ax +80105a77: 66 90 xchg %ax,%ax +80105a79: 66 90 xchg %ax,%ax +80105a7b: 66 90 xchg %ax,%ax +80105a7d: 66 90 xchg %ax,%ax +80105a7f: 90 nop + +80105a80 : +struct gatedesc idt[256]; +extern uint vectors[]; // in vectors.S: array of 256 entry pointers +struct spinlock tickslock; +uint ticks; + +void tvinit(void) { +80105a80: 55 push %ebp + int i; + + for (i = 0; i < 256; i++) { +80105a81: 31 c0 xor %eax,%eax +void tvinit(void) { +80105a83: 89 e5 mov %esp,%ebp +80105a85: 83 ec 08 sub $0x8,%esp +80105a88: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105a8f: 90 nop + SETGATE(idt[i], 0, SEG_KCODE << 3, vectors[i], 0); +80105a90: 8b 14 85 08 a0 10 80 mov -0x7fef5ff8(,%eax,4),%edx +80105a97: c7 04 c5 e2 3c 11 80 movl $0x8e000008,-0x7feec31e(,%eax,8) +80105a9e: 08 00 00 8e +80105aa2: 66 89 14 c5 e0 3c 11 mov %dx,-0x7feec320(,%eax,8) +80105aa9: 80 +80105aaa: c1 ea 10 shr $0x10,%edx +80105aad: 66 89 14 c5 e6 3c 11 mov %dx,-0x7feec31a(,%eax,8) +80105ab4: 80 + for (i = 0; i < 256; i++) { +80105ab5: 83 c0 01 add $0x1,%eax +80105ab8: 3d 00 01 00 00 cmp $0x100,%eax +80105abd: 75 d1 jne 80105a90 + } + SETGATE(idt[T_SYSCALL], 1, SEG_KCODE << 3, vectors[T_SYSCALL], DPL_USER); + + initlock(&tickslock, "time"); +80105abf: 83 ec 08 sub $0x8,%esp + SETGATE(idt[T_SYSCALL], 1, SEG_KCODE << 3, vectors[T_SYSCALL], DPL_USER); +80105ac2: a1 08 a1 10 80 mov 0x8010a108,%eax +80105ac7: c7 05 e2 3e 11 80 08 movl $0xef000008,0x80113ee2 +80105ace: 00 00 ef + initlock(&tickslock, "time"); +80105ad1: 68 72 7b 10 80 push $0x80107b72 +80105ad6: 68 a0 3c 11 80 push $0x80113ca0 + SETGATE(idt[T_SYSCALL], 1, SEG_KCODE << 3, vectors[T_SYSCALL], DPL_USER); +80105adb: 66 a3 e0 3e 11 80 mov %ax,0x80113ee0 +80105ae1: c1 e8 10 shr $0x10,%eax +80105ae4: 66 a3 e6 3e 11 80 mov %ax,0x80113ee6 + initlock(&tickslock, "time"); +80105aea: e8 41 ea ff ff call 80104530 +} +80105aef: 83 c4 10 add $0x10,%esp +80105af2: c9 leave +80105af3: c3 ret +80105af4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105afb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80105aff: 90 nop + +80105b00 : + +void idtinit(void) { +80105b00: 55 push %ebp + pd[0] = size - 1; +80105b01: b8 ff 07 00 00 mov $0x7ff,%eax +80105b06: 89 e5 mov %esp,%ebp +80105b08: 83 ec 10 sub $0x10,%esp +80105b0b: 66 89 45 fa mov %ax,-0x6(%ebp) + pd[1] = (uint)p; +80105b0f: b8 e0 3c 11 80 mov $0x80113ce0,%eax +80105b14: 66 89 45 fc mov %ax,-0x4(%ebp) + pd[2] = (uint)p >> 16; +80105b18: c1 e8 10 shr $0x10,%eax +80105b1b: 66 89 45 fe mov %ax,-0x2(%ebp) + asm volatile ("lidt (%0)" : : "r" (pd)); +80105b1f: 8d 45 fa lea -0x6(%ebp),%eax +80105b22: 0f 01 18 lidtl (%eax) + lidt(idt, sizeof(idt)); +} +80105b25: c9 leave +80105b26: c3 ret +80105b27: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105b2e: 66 90 xchg %ax,%ax + +80105b30 : + +void trap(struct trapframe *tf) { +80105b30: 55 push %ebp +80105b31: 89 e5 mov %esp,%ebp +80105b33: 57 push %edi +80105b34: 56 push %esi +80105b35: 53 push %ebx +80105b36: 83 ec 1c sub $0x1c,%esp +80105b39: 8b 5d 08 mov 0x8(%ebp),%ebx + if (tf->trapno == T_SYSCALL) { +80105b3c: 8b 43 30 mov 0x30(%ebx),%eax +80105b3f: 83 f8 40 cmp $0x40,%eax +80105b42: 0f 84 68 01 00 00 je 80105cb0 + exit(); + } + return; + } + + switch (tf->trapno) { +80105b48: 83 e8 20 sub $0x20,%eax +80105b4b: 83 f8 1f cmp $0x1f,%eax +80105b4e: 0f 87 8c 00 00 00 ja 80105be0 +80105b54: ff 24 85 18 7c 10 80 jmp *-0x7fef83e8(,%eax,4) +80105b5b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80105b5f: 90 nop + release(&tickslock); + } + lapiceoi(); + break; + case T_IRQ0 + IRQ_IDE: + ideintr(); +80105b60: e8 fb c7 ff ff call 80102360 + lapiceoi(); +80105b65: e8 c6 ce ff ff call 80102a30 + } + + // Force process exit if it has been killed and is in user space. + // (If it is still executing in the kernel, let it keep running + // until it gets to the regular system call return.) + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { +80105b6a: e8 61 df ff ff call 80103ad0 +80105b6f: 85 c0 test %eax,%eax +80105b71: 74 1d je 80105b90 +80105b73: e8 58 df ff ff call 80103ad0 +80105b78: 8b 50 24 mov 0x24(%eax),%edx +80105b7b: 85 d2 test %edx,%edx +80105b7d: 74 11 je 80105b90 +80105b7f: 0f b7 43 3c movzwl 0x3c(%ebx),%eax +80105b83: 83 e0 03 and $0x3,%eax +80105b86: 66 83 f8 03 cmp $0x3,%ax +80105b8a: 0f 84 e8 01 00 00 je 80105d78 + exit(); + } + + // Force process to give up CPU on clock tick. + // If interrupts were on while locks held, would need to check nlock. + if (myproc() && myproc()->state == RUNNING && +80105b90: e8 3b df ff ff call 80103ad0 +80105b95: 85 c0 test %eax,%eax +80105b97: 74 0f je 80105ba8 +80105b99: e8 32 df ff ff call 80103ad0 +80105b9e: 83 78 0c 04 cmpl $0x4,0xc(%eax) +80105ba2: 0f 84 b8 00 00 00 je 80105c60 + tf->trapno == T_IRQ0 + IRQ_TIMER) { + yield(); + } + + // Check if the process has been killed since we yielded + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { +80105ba8: e8 23 df ff ff call 80103ad0 +80105bad: 85 c0 test %eax,%eax +80105baf: 74 1d je 80105bce +80105bb1: e8 1a df ff ff call 80103ad0 +80105bb6: 8b 40 24 mov 0x24(%eax),%eax +80105bb9: 85 c0 test %eax,%eax +80105bbb: 74 11 je 80105bce +80105bbd: 0f b7 43 3c movzwl 0x3c(%ebx),%eax +80105bc1: 83 e0 03 and $0x3,%eax +80105bc4: 66 83 f8 03 cmp $0x3,%ax +80105bc8: 0f 84 0f 01 00 00 je 80105cdd + exit(); + } +} +80105bce: 8d 65 f4 lea -0xc(%ebp),%esp +80105bd1: 5b pop %ebx +80105bd2: 5e pop %esi +80105bd3: 5f pop %edi +80105bd4: 5d pop %ebp +80105bd5: c3 ret +80105bd6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105bdd: 8d 76 00 lea 0x0(%esi),%esi + if (myproc() == 0 || (tf->cs & 3) == 0) { +80105be0: e8 eb de ff ff call 80103ad0 +80105be5: 8b 7b 38 mov 0x38(%ebx),%edi +80105be8: 85 c0 test %eax,%eax +80105bea: 0f 84 a2 01 00 00 je 80105d92 +80105bf0: f6 43 3c 03 testb $0x3,0x3c(%ebx) +80105bf4: 0f 84 98 01 00 00 je 80105d92 + return result; +} + +static inline uint rcr2(void) { + uint val; + asm volatile ("movl %%cr2,%0" : "=r" (val)); +80105bfa: 0f 20 d1 mov %cr2,%ecx +80105bfd: 89 4d d8 mov %ecx,-0x28(%ebp) + cprintf("pid %d %s: trap %d err %d on cpu %d " +80105c00: e8 ab de ff ff call 80103ab0 +80105c05: 8b 73 30 mov 0x30(%ebx),%esi +80105c08: 89 45 dc mov %eax,-0x24(%ebp) +80105c0b: 8b 43 34 mov 0x34(%ebx),%eax +80105c0e: 89 45 e4 mov %eax,-0x1c(%ebp) + myproc()->pid, myproc()->name, tf->trapno, +80105c11: e8 ba de ff ff call 80103ad0 +80105c16: 89 45 e0 mov %eax,-0x20(%ebp) +80105c19: e8 b2 de ff ff call 80103ad0 + cprintf("pid %d %s: trap %d err %d on cpu %d " +80105c1e: 8b 4d d8 mov -0x28(%ebp),%ecx +80105c21: 8b 55 dc mov -0x24(%ebp),%edx +80105c24: 51 push %ecx +80105c25: 57 push %edi +80105c26: 52 push %edx +80105c27: ff 75 e4 push -0x1c(%ebp) +80105c2a: 56 push %esi + myproc()->pid, myproc()->name, tf->trapno, +80105c2b: 8b 75 e0 mov -0x20(%ebp),%esi +80105c2e: 83 c6 6c add $0x6c,%esi + cprintf("pid %d %s: trap %d err %d on cpu %d " +80105c31: 56 push %esi +80105c32: ff 70 10 push 0x10(%eax) +80105c35: 68 d4 7b 10 80 push $0x80107bd4 +80105c3a: e8 71 aa ff ff call 801006b0 + myproc()->killed = 1; +80105c3f: 83 c4 20 add $0x20,%esp +80105c42: e8 89 de ff ff call 80103ad0 +80105c47: c7 40 24 01 00 00 00 movl $0x1,0x24(%eax) + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { +80105c4e: e8 7d de ff ff call 80103ad0 +80105c53: 85 c0 test %eax,%eax +80105c55: 0f 85 18 ff ff ff jne 80105b73 +80105c5b: e9 30 ff ff ff jmp 80105b90 + if (myproc() && myproc()->state == RUNNING && +80105c60: 83 7b 30 20 cmpl $0x20,0x30(%ebx) +80105c64: 0f 85 3e ff ff ff jne 80105ba8 + yield(); +80105c6a: e8 e1 e4 ff ff call 80104150 +80105c6f: e9 34 ff ff ff jmp 80105ba8 +80105c74: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + cprintf("cpu%d: spurious interrupt at %x:%x\n", +80105c78: 8b 7b 38 mov 0x38(%ebx),%edi +80105c7b: 0f b7 73 3c movzwl 0x3c(%ebx),%esi +80105c7f: e8 2c de ff ff call 80103ab0 +80105c84: 57 push %edi +80105c85: 56 push %esi +80105c86: 50 push %eax +80105c87: 68 7c 7b 10 80 push $0x80107b7c +80105c8c: e8 1f aa ff ff call 801006b0 + lapiceoi(); +80105c91: e8 9a cd ff ff call 80102a30 + break; +80105c96: 83 c4 10 add $0x10,%esp + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { +80105c99: e8 32 de ff ff call 80103ad0 +80105c9e: 85 c0 test %eax,%eax +80105ca0: 0f 85 cd fe ff ff jne 80105b73 +80105ca6: e9 e5 fe ff ff jmp 80105b90 +80105cab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80105caf: 90 nop + if (myproc()->killed) { +80105cb0: e8 1b de ff ff call 80103ad0 +80105cb5: 8b 70 24 mov 0x24(%eax),%esi +80105cb8: 85 f6 test %esi,%esi +80105cba: 0f 85 c8 00 00 00 jne 80105d88 + myproc()->tf = tf; +80105cc0: e8 0b de ff ff call 80103ad0 +80105cc5: 89 58 18 mov %ebx,0x18(%eax) + syscall(); +80105cc8: e8 f3 ee ff ff call 80104bc0 + if (myproc()->killed) { +80105ccd: e8 fe dd ff ff call 80103ad0 +80105cd2: 8b 48 24 mov 0x24(%eax),%ecx +80105cd5: 85 c9 test %ecx,%ecx +80105cd7: 0f 84 f1 fe ff ff je 80105bce +} +80105cdd: 8d 65 f4 lea -0xc(%ebp),%esp +80105ce0: 5b pop %ebx +80105ce1: 5e pop %esi +80105ce2: 5f pop %edi +80105ce3: 5d pop %ebp + exit(); +80105ce4: e9 07 e2 ff ff jmp 80103ef0 +80105ce9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + uartintr(); +80105cf0: e8 3b 02 00 00 call 80105f30 + lapiceoi(); +80105cf5: e8 36 cd ff ff call 80102a30 + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { +80105cfa: e8 d1 dd ff ff call 80103ad0 +80105cff: 85 c0 test %eax,%eax +80105d01: 0f 85 6c fe ff ff jne 80105b73 +80105d07: e9 84 fe ff ff jmp 80105b90 +80105d0c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + kbdintr(); +80105d10: e8 db cb ff ff call 801028f0 + lapiceoi(); +80105d15: e8 16 cd ff ff call 80102a30 + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { +80105d1a: e8 b1 dd ff ff call 80103ad0 +80105d1f: 85 c0 test %eax,%eax +80105d21: 0f 85 4c fe ff ff jne 80105b73 +80105d27: e9 64 fe ff ff jmp 80105b90 +80105d2c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (cpuid() == 0) { +80105d30: e8 7b dd ff ff call 80103ab0 +80105d35: 85 c0 test %eax,%eax +80105d37: 0f 85 28 fe ff ff jne 80105b65 + acquire(&tickslock); +80105d3d: 83 ec 0c sub $0xc,%esp +80105d40: 68 a0 3c 11 80 push $0x80113ca0 +80105d45: e8 b6 e9 ff ff call 80104700 + wakeup(&ticks); +80105d4a: c7 04 24 80 3c 11 80 movl $0x80113c80,(%esp) + ticks++; +80105d51: 83 05 80 3c 11 80 01 addl $0x1,0x80113c80 + wakeup(&ticks); +80105d58: e8 03 e5 ff ff call 80104260 + release(&tickslock); +80105d5d: c7 04 24 a0 3c 11 80 movl $0x80113ca0,(%esp) +80105d64: e8 37 e9 ff ff call 801046a0 +80105d69: 83 c4 10 add $0x10,%esp + lapiceoi(); +80105d6c: e9 f4 fd ff ff jmp 80105b65 +80105d71: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + exit(); +80105d78: e8 73 e1 ff ff call 80103ef0 +80105d7d: e9 0e fe ff ff jmp 80105b90 +80105d82: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + exit(); +80105d88: e8 63 e1 ff ff call 80103ef0 +80105d8d: e9 2e ff ff ff jmp 80105cc0 +80105d92: 0f 20 d6 mov %cr2,%esi + cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n", +80105d95: e8 16 dd ff ff call 80103ab0 +80105d9a: 83 ec 0c sub $0xc,%esp +80105d9d: 56 push %esi +80105d9e: 57 push %edi +80105d9f: 50 push %eax +80105da0: ff 73 30 push 0x30(%ebx) +80105da3: 68 a0 7b 10 80 push $0x80107ba0 +80105da8: e8 03 a9 ff ff call 801006b0 + panic("trap"); +80105dad: 83 c4 14 add $0x14,%esp +80105db0: 68 77 7b 10 80 push $0x80107b77 +80105db5: e8 d6 a5 ff ff call 80100390 +80105dba: 66 90 xchg %ax,%ax +80105dbc: 66 90 xchg %ax,%ax +80105dbe: 66 90 xchg %ax,%ax + +80105dc0 : + } + outb(COM1 + 0, c); +} + +static int uartgetc(void) { + if (!uart) { +80105dc0: a1 e0 44 11 80 mov 0x801144e0,%eax +80105dc5: 85 c0 test %eax,%eax +80105dc7: 74 17 je 80105de0 + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80105dc9: ba fd 03 00 00 mov $0x3fd,%edx +80105dce: ec in (%dx),%al + return -1; + } + if (!(inb(COM1 + 5) & 0x01)) { +80105dcf: a8 01 test $0x1,%al +80105dd1: 74 0d je 80105de0 +80105dd3: ba f8 03 00 00 mov $0x3f8,%edx +80105dd8: ec in (%dx),%al + return -1; + } + return inb(COM1 + 0); +80105dd9: 0f b6 c0 movzbl %al,%eax +80105ddc: c3 ret +80105ddd: 8d 76 00 lea 0x0(%esi),%esi + return -1; +80105de0: b8 ff ff ff ff mov $0xffffffff,%eax +} +80105de5: c3 ret +80105de6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105ded: 8d 76 00 lea 0x0(%esi),%esi + +80105df0 : +void uartinit(void) { +80105df0: 55 push %ebp + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80105df1: 31 c9 xor %ecx,%ecx +80105df3: 89 c8 mov %ecx,%eax +80105df5: 89 e5 mov %esp,%ebp +80105df7: 57 push %edi +80105df8: bf fa 03 00 00 mov $0x3fa,%edi +80105dfd: 56 push %esi +80105dfe: 89 fa mov %edi,%edx +80105e00: 53 push %ebx +80105e01: 83 ec 1c sub $0x1c,%esp +80105e04: ee out %al,(%dx) +80105e05: be fb 03 00 00 mov $0x3fb,%esi +80105e0a: b8 80 ff ff ff mov $0xffffff80,%eax +80105e0f: 89 f2 mov %esi,%edx +80105e11: ee out %al,(%dx) +80105e12: b8 0c 00 00 00 mov $0xc,%eax +80105e17: ba f8 03 00 00 mov $0x3f8,%edx +80105e1c: ee out %al,(%dx) +80105e1d: bb f9 03 00 00 mov $0x3f9,%ebx +80105e22: 89 c8 mov %ecx,%eax +80105e24: 89 da mov %ebx,%edx +80105e26: ee out %al,(%dx) +80105e27: b8 03 00 00 00 mov $0x3,%eax +80105e2c: 89 f2 mov %esi,%edx +80105e2e: ee out %al,(%dx) +80105e2f: ba fc 03 00 00 mov $0x3fc,%edx +80105e34: 89 c8 mov %ecx,%eax +80105e36: ee out %al,(%dx) +80105e37: b8 01 00 00 00 mov $0x1,%eax +80105e3c: 89 da mov %ebx,%edx +80105e3e: ee out %al,(%dx) + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80105e3f: ba fd 03 00 00 mov $0x3fd,%edx +80105e44: ec in (%dx),%al + if (inb(COM1 + 5) == 0xFF) { +80105e45: 3c ff cmp $0xff,%al +80105e47: 74 78 je 80105ec1 + uart = 1; +80105e49: c7 05 e0 44 11 80 01 movl $0x1,0x801144e0 +80105e50: 00 00 00 +80105e53: 89 fa mov %edi,%edx +80105e55: ec in (%dx),%al +80105e56: ba f8 03 00 00 mov $0x3f8,%edx +80105e5b: ec in (%dx),%al + ioapicenable(IRQ_COM1, 0); +80105e5c: 83 ec 08 sub $0x8,%esp + for (p = "xv6...\n"; *p; p++) { +80105e5f: bf 98 7c 10 80 mov $0x80107c98,%edi +80105e64: be fd 03 00 00 mov $0x3fd,%esi + ioapicenable(IRQ_COM1, 0); +80105e69: 6a 00 push $0x0 +80105e6b: 6a 04 push $0x4 +80105e6d: e8 2e c7 ff ff call 801025a0 + for (p = "xv6...\n"; *p; p++) { +80105e72: c6 45 e7 78 movb $0x78,-0x19(%ebp) + ioapicenable(IRQ_COM1, 0); +80105e76: 83 c4 10 add $0x10,%esp +80105e79: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + if (!uart) { +80105e80: a1 e0 44 11 80 mov 0x801144e0,%eax +80105e85: bb 80 00 00 00 mov $0x80,%ebx +80105e8a: 85 c0 test %eax,%eax +80105e8c: 75 14 jne 80105ea2 +80105e8e: eb 23 jmp 80105eb3 + microdelay(10); +80105e90: 83 ec 0c sub $0xc,%esp +80105e93: 6a 0a push $0xa +80105e95: e8 b6 cb ff ff call 80102a50 + for (i = 0; i < 128 && !(inb(COM1 + 5) & 0x20); i++) { +80105e9a: 83 c4 10 add $0x10,%esp +80105e9d: 83 eb 01 sub $0x1,%ebx +80105ea0: 74 07 je 80105ea9 +80105ea2: 89 f2 mov %esi,%edx +80105ea4: ec in (%dx),%al +80105ea5: a8 20 test $0x20,%al +80105ea7: 74 e7 je 80105e90 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80105ea9: 0f b6 45 e7 movzbl -0x19(%ebp),%eax +80105ead: ba f8 03 00 00 mov $0x3f8,%edx +80105eb2: ee out %al,(%dx) + for (p = "xv6...\n"; *p; p++) { +80105eb3: 0f b6 47 01 movzbl 0x1(%edi),%eax +80105eb7: 83 c7 01 add $0x1,%edi +80105eba: 88 45 e7 mov %al,-0x19(%ebp) +80105ebd: 84 c0 test %al,%al +80105ebf: 75 bf jne 80105e80 +} +80105ec1: 8d 65 f4 lea -0xc(%ebp),%esp +80105ec4: 5b pop %ebx +80105ec5: 5e pop %esi +80105ec6: 5f pop %edi +80105ec7: 5d pop %ebp +80105ec8: c3 ret +80105ec9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80105ed0 : + if (!uart) { +80105ed0: a1 e0 44 11 80 mov 0x801144e0,%eax +80105ed5: 85 c0 test %eax,%eax +80105ed7: 74 47 je 80105f20 +void uartputc(int c) { +80105ed9: 55 push %ebp +80105eda: 89 e5 mov %esp,%ebp +80105edc: 56 push %esi + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); +80105edd: be fd 03 00 00 mov $0x3fd,%esi +80105ee2: 53 push %ebx +80105ee3: bb 80 00 00 00 mov $0x80,%ebx +80105ee8: eb 18 jmp 80105f02 +80105eea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + microdelay(10); +80105ef0: 83 ec 0c sub $0xc,%esp +80105ef3: 6a 0a push $0xa +80105ef5: e8 56 cb ff ff call 80102a50 + for (i = 0; i < 128 && !(inb(COM1 + 5) & 0x20); i++) { +80105efa: 83 c4 10 add $0x10,%esp +80105efd: 83 eb 01 sub $0x1,%ebx +80105f00: 74 07 je 80105f09 +80105f02: 89 f2 mov %esi,%edx +80105f04: ec in (%dx),%al +80105f05: a8 20 test $0x20,%al +80105f07: 74 e7 je 80105ef0 + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +80105f09: 8b 45 08 mov 0x8(%ebp),%eax +80105f0c: ba f8 03 00 00 mov $0x3f8,%edx +80105f11: ee out %al,(%dx) +} +80105f12: 8d 65 f8 lea -0x8(%ebp),%esp +80105f15: 5b pop %ebx +80105f16: 5e pop %esi +80105f17: 5d pop %ebp +80105f18: c3 ret +80105f19: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105f20: c3 ret +80105f21: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105f28: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80105f2f: 90 nop + +80105f30 : + +void uartintr(void) { +80105f30: 55 push %ebp +80105f31: 89 e5 mov %esp,%ebp +80105f33: 83 ec 14 sub $0x14,%esp + consoleintr(uartgetc); +80105f36: 68 c0 5d 10 80 push $0x80105dc0 +80105f3b: e8 a0 a9 ff ff call 801008e0 +} +80105f40: 83 c4 10 add $0x10,%esp +80105f43: c9 leave +80105f44: c3 ret + +80105f45 : +# generated by vectors.pl - do not edit +# handlers +.globl alltraps +.globl vector0 +vector0: + pushl $0 +80105f45: 6a 00 push $0x0 + pushl $0 +80105f47: 6a 00 push $0x0 + jmp alltraps +80105f49: e9 00 fb ff ff jmp 80105a4e + +80105f4e : +.globl vector1 +vector1: + pushl $0 +80105f4e: 6a 00 push $0x0 + pushl $1 +80105f50: 6a 01 push $0x1 + jmp alltraps +80105f52: e9 f7 fa ff ff jmp 80105a4e + +80105f57 : +.globl vector2 +vector2: + pushl $0 +80105f57: 6a 00 push $0x0 + pushl $2 +80105f59: 6a 02 push $0x2 + jmp alltraps +80105f5b: e9 ee fa ff ff jmp 80105a4e + +80105f60 : +.globl vector3 +vector3: + pushl $0 +80105f60: 6a 00 push $0x0 + pushl $3 +80105f62: 6a 03 push $0x3 + jmp alltraps +80105f64: e9 e5 fa ff ff jmp 80105a4e + +80105f69 : +.globl vector4 +vector4: + pushl $0 +80105f69: 6a 00 push $0x0 + pushl $4 +80105f6b: 6a 04 push $0x4 + jmp alltraps +80105f6d: e9 dc fa ff ff jmp 80105a4e + +80105f72 : +.globl vector5 +vector5: + pushl $0 +80105f72: 6a 00 push $0x0 + pushl $5 +80105f74: 6a 05 push $0x5 + jmp alltraps +80105f76: e9 d3 fa ff ff jmp 80105a4e + +80105f7b : +.globl vector6 +vector6: + pushl $0 +80105f7b: 6a 00 push $0x0 + pushl $6 +80105f7d: 6a 06 push $0x6 + jmp alltraps +80105f7f: e9 ca fa ff ff jmp 80105a4e + +80105f84 : +.globl vector7 +vector7: + pushl $0 +80105f84: 6a 00 push $0x0 + pushl $7 +80105f86: 6a 07 push $0x7 + jmp alltraps +80105f88: e9 c1 fa ff ff jmp 80105a4e + +80105f8d : +.globl vector8 +vector8: + pushl $8 +80105f8d: 6a 08 push $0x8 + jmp alltraps +80105f8f: e9 ba fa ff ff jmp 80105a4e + +80105f94 : +.globl vector9 +vector9: + pushl $0 +80105f94: 6a 00 push $0x0 + pushl $9 +80105f96: 6a 09 push $0x9 + jmp alltraps +80105f98: e9 b1 fa ff ff jmp 80105a4e + +80105f9d : +.globl vector10 +vector10: + pushl $10 +80105f9d: 6a 0a push $0xa + jmp alltraps +80105f9f: e9 aa fa ff ff jmp 80105a4e + +80105fa4 : +.globl vector11 +vector11: + pushl $11 +80105fa4: 6a 0b push $0xb + jmp alltraps +80105fa6: e9 a3 fa ff ff jmp 80105a4e + +80105fab : +.globl vector12 +vector12: + pushl $12 +80105fab: 6a 0c push $0xc + jmp alltraps +80105fad: e9 9c fa ff ff jmp 80105a4e + +80105fb2 : +.globl vector13 +vector13: + pushl $13 +80105fb2: 6a 0d push $0xd + jmp alltraps +80105fb4: e9 95 fa ff ff jmp 80105a4e + +80105fb9 : +.globl vector14 +vector14: + pushl $14 +80105fb9: 6a 0e push $0xe + jmp alltraps +80105fbb: e9 8e fa ff ff jmp 80105a4e + +80105fc0 : +.globl vector15 +vector15: + pushl $0 +80105fc0: 6a 00 push $0x0 + pushl $15 +80105fc2: 6a 0f push $0xf + jmp alltraps +80105fc4: e9 85 fa ff ff jmp 80105a4e + +80105fc9 : +.globl vector16 +vector16: + pushl $0 +80105fc9: 6a 00 push $0x0 + pushl $16 +80105fcb: 6a 10 push $0x10 + jmp alltraps +80105fcd: e9 7c fa ff ff jmp 80105a4e + +80105fd2 : +.globl vector17 +vector17: + pushl $17 +80105fd2: 6a 11 push $0x11 + jmp alltraps +80105fd4: e9 75 fa ff ff jmp 80105a4e + +80105fd9 : +.globl vector18 +vector18: + pushl $0 +80105fd9: 6a 00 push $0x0 + pushl $18 +80105fdb: 6a 12 push $0x12 + jmp alltraps +80105fdd: e9 6c fa ff ff jmp 80105a4e + +80105fe2 : +.globl vector19 +vector19: + pushl $0 +80105fe2: 6a 00 push $0x0 + pushl $19 +80105fe4: 6a 13 push $0x13 + jmp alltraps +80105fe6: e9 63 fa ff ff jmp 80105a4e + +80105feb : +.globl vector20 +vector20: + pushl $0 +80105feb: 6a 00 push $0x0 + pushl $20 +80105fed: 6a 14 push $0x14 + jmp alltraps +80105fef: e9 5a fa ff ff jmp 80105a4e + +80105ff4 : +.globl vector21 +vector21: + pushl $0 +80105ff4: 6a 00 push $0x0 + pushl $21 +80105ff6: 6a 15 push $0x15 + jmp alltraps +80105ff8: e9 51 fa ff ff jmp 80105a4e + +80105ffd : +.globl vector22 +vector22: + pushl $0 +80105ffd: 6a 00 push $0x0 + pushl $22 +80105fff: 6a 16 push $0x16 + jmp alltraps +80106001: e9 48 fa ff ff jmp 80105a4e + +80106006 : +.globl vector23 +vector23: + pushl $0 +80106006: 6a 00 push $0x0 + pushl $23 +80106008: 6a 17 push $0x17 + jmp alltraps +8010600a: e9 3f fa ff ff jmp 80105a4e + +8010600f : +.globl vector24 +vector24: + pushl $0 +8010600f: 6a 00 push $0x0 + pushl $24 +80106011: 6a 18 push $0x18 + jmp alltraps +80106013: e9 36 fa ff ff jmp 80105a4e + +80106018 : +.globl vector25 +vector25: + pushl $0 +80106018: 6a 00 push $0x0 + pushl $25 +8010601a: 6a 19 push $0x19 + jmp alltraps +8010601c: e9 2d fa ff ff jmp 80105a4e + +80106021 : +.globl vector26 +vector26: + pushl $0 +80106021: 6a 00 push $0x0 + pushl $26 +80106023: 6a 1a push $0x1a + jmp alltraps +80106025: e9 24 fa ff ff jmp 80105a4e + +8010602a : +.globl vector27 +vector27: + pushl $0 +8010602a: 6a 00 push $0x0 + pushl $27 +8010602c: 6a 1b push $0x1b + jmp alltraps +8010602e: e9 1b fa ff ff jmp 80105a4e + +80106033 : +.globl vector28 +vector28: + pushl $0 +80106033: 6a 00 push $0x0 + pushl $28 +80106035: 6a 1c push $0x1c + jmp alltraps +80106037: e9 12 fa ff ff jmp 80105a4e + +8010603c : +.globl vector29 +vector29: + pushl $0 +8010603c: 6a 00 push $0x0 + pushl $29 +8010603e: 6a 1d push $0x1d + jmp alltraps +80106040: e9 09 fa ff ff jmp 80105a4e + +80106045 : +.globl vector30 +vector30: + pushl $0 +80106045: 6a 00 push $0x0 + pushl $30 +80106047: 6a 1e push $0x1e + jmp alltraps +80106049: e9 00 fa ff ff jmp 80105a4e + +8010604e : +.globl vector31 +vector31: + pushl $0 +8010604e: 6a 00 push $0x0 + pushl $31 +80106050: 6a 1f push $0x1f + jmp alltraps +80106052: e9 f7 f9 ff ff jmp 80105a4e + +80106057 : +.globl vector32 +vector32: + pushl $0 +80106057: 6a 00 push $0x0 + pushl $32 +80106059: 6a 20 push $0x20 + jmp alltraps +8010605b: e9 ee f9 ff ff jmp 80105a4e + +80106060 : +.globl vector33 +vector33: + pushl $0 +80106060: 6a 00 push $0x0 + pushl $33 +80106062: 6a 21 push $0x21 + jmp alltraps +80106064: e9 e5 f9 ff ff jmp 80105a4e + +80106069 : +.globl vector34 +vector34: + pushl $0 +80106069: 6a 00 push $0x0 + pushl $34 +8010606b: 6a 22 push $0x22 + jmp alltraps +8010606d: e9 dc f9 ff ff jmp 80105a4e + +80106072 : +.globl vector35 +vector35: + pushl $0 +80106072: 6a 00 push $0x0 + pushl $35 +80106074: 6a 23 push $0x23 + jmp alltraps +80106076: e9 d3 f9 ff ff jmp 80105a4e + +8010607b : +.globl vector36 +vector36: + pushl $0 +8010607b: 6a 00 push $0x0 + pushl $36 +8010607d: 6a 24 push $0x24 + jmp alltraps +8010607f: e9 ca f9 ff ff jmp 80105a4e + +80106084 : +.globl vector37 +vector37: + pushl $0 +80106084: 6a 00 push $0x0 + pushl $37 +80106086: 6a 25 push $0x25 + jmp alltraps +80106088: e9 c1 f9 ff ff jmp 80105a4e + +8010608d : +.globl vector38 +vector38: + pushl $0 +8010608d: 6a 00 push $0x0 + pushl $38 +8010608f: 6a 26 push $0x26 + jmp alltraps +80106091: e9 b8 f9 ff ff jmp 80105a4e + +80106096 : +.globl vector39 +vector39: + pushl $0 +80106096: 6a 00 push $0x0 + pushl $39 +80106098: 6a 27 push $0x27 + jmp alltraps +8010609a: e9 af f9 ff ff jmp 80105a4e + +8010609f : +.globl vector40 +vector40: + pushl $0 +8010609f: 6a 00 push $0x0 + pushl $40 +801060a1: 6a 28 push $0x28 + jmp alltraps +801060a3: e9 a6 f9 ff ff jmp 80105a4e + +801060a8 : +.globl vector41 +vector41: + pushl $0 +801060a8: 6a 00 push $0x0 + pushl $41 +801060aa: 6a 29 push $0x29 + jmp alltraps +801060ac: e9 9d f9 ff ff jmp 80105a4e + +801060b1 : +.globl vector42 +vector42: + pushl $0 +801060b1: 6a 00 push $0x0 + pushl $42 +801060b3: 6a 2a push $0x2a + jmp alltraps +801060b5: e9 94 f9 ff ff jmp 80105a4e + +801060ba : +.globl vector43 +vector43: + pushl $0 +801060ba: 6a 00 push $0x0 + pushl $43 +801060bc: 6a 2b push $0x2b + jmp alltraps +801060be: e9 8b f9 ff ff jmp 80105a4e + +801060c3 : +.globl vector44 +vector44: + pushl $0 +801060c3: 6a 00 push $0x0 + pushl $44 +801060c5: 6a 2c push $0x2c + jmp alltraps +801060c7: e9 82 f9 ff ff jmp 80105a4e + +801060cc : +.globl vector45 +vector45: + pushl $0 +801060cc: 6a 00 push $0x0 + pushl $45 +801060ce: 6a 2d push $0x2d + jmp alltraps +801060d0: e9 79 f9 ff ff jmp 80105a4e + +801060d5 : +.globl vector46 +vector46: + pushl $0 +801060d5: 6a 00 push $0x0 + pushl $46 +801060d7: 6a 2e push $0x2e + jmp alltraps +801060d9: e9 70 f9 ff ff jmp 80105a4e + +801060de : +.globl vector47 +vector47: + pushl $0 +801060de: 6a 00 push $0x0 + pushl $47 +801060e0: 6a 2f push $0x2f + jmp alltraps +801060e2: e9 67 f9 ff ff jmp 80105a4e + +801060e7 : +.globl vector48 +vector48: + pushl $0 +801060e7: 6a 00 push $0x0 + pushl $48 +801060e9: 6a 30 push $0x30 + jmp alltraps +801060eb: e9 5e f9 ff ff jmp 80105a4e + +801060f0 : +.globl vector49 +vector49: + pushl $0 +801060f0: 6a 00 push $0x0 + pushl $49 +801060f2: 6a 31 push $0x31 + jmp alltraps +801060f4: e9 55 f9 ff ff jmp 80105a4e + +801060f9 : +.globl vector50 +vector50: + pushl $0 +801060f9: 6a 00 push $0x0 + pushl $50 +801060fb: 6a 32 push $0x32 + jmp alltraps +801060fd: e9 4c f9 ff ff jmp 80105a4e + +80106102 : +.globl vector51 +vector51: + pushl $0 +80106102: 6a 00 push $0x0 + pushl $51 +80106104: 6a 33 push $0x33 + jmp alltraps +80106106: e9 43 f9 ff ff jmp 80105a4e + +8010610b : +.globl vector52 +vector52: + pushl $0 +8010610b: 6a 00 push $0x0 + pushl $52 +8010610d: 6a 34 push $0x34 + jmp alltraps +8010610f: e9 3a f9 ff ff jmp 80105a4e + +80106114 : +.globl vector53 +vector53: + pushl $0 +80106114: 6a 00 push $0x0 + pushl $53 +80106116: 6a 35 push $0x35 + jmp alltraps +80106118: e9 31 f9 ff ff jmp 80105a4e + +8010611d : +.globl vector54 +vector54: + pushl $0 +8010611d: 6a 00 push $0x0 + pushl $54 +8010611f: 6a 36 push $0x36 + jmp alltraps +80106121: e9 28 f9 ff ff jmp 80105a4e + +80106126 : +.globl vector55 +vector55: + pushl $0 +80106126: 6a 00 push $0x0 + pushl $55 +80106128: 6a 37 push $0x37 + jmp alltraps +8010612a: e9 1f f9 ff ff jmp 80105a4e + +8010612f : +.globl vector56 +vector56: + pushl $0 +8010612f: 6a 00 push $0x0 + pushl $56 +80106131: 6a 38 push $0x38 + jmp alltraps +80106133: e9 16 f9 ff ff jmp 80105a4e + +80106138 : +.globl vector57 +vector57: + pushl $0 +80106138: 6a 00 push $0x0 + pushl $57 +8010613a: 6a 39 push $0x39 + jmp alltraps +8010613c: e9 0d f9 ff ff jmp 80105a4e + +80106141 : +.globl vector58 +vector58: + pushl $0 +80106141: 6a 00 push $0x0 + pushl $58 +80106143: 6a 3a push $0x3a + jmp alltraps +80106145: e9 04 f9 ff ff jmp 80105a4e + +8010614a : +.globl vector59 +vector59: + pushl $0 +8010614a: 6a 00 push $0x0 + pushl $59 +8010614c: 6a 3b push $0x3b + jmp alltraps +8010614e: e9 fb f8 ff ff jmp 80105a4e + +80106153 : +.globl vector60 +vector60: + pushl $0 +80106153: 6a 00 push $0x0 + pushl $60 +80106155: 6a 3c push $0x3c + jmp alltraps +80106157: e9 f2 f8 ff ff jmp 80105a4e + +8010615c : +.globl vector61 +vector61: + pushl $0 +8010615c: 6a 00 push $0x0 + pushl $61 +8010615e: 6a 3d push $0x3d + jmp alltraps +80106160: e9 e9 f8 ff ff jmp 80105a4e + +80106165 : +.globl vector62 +vector62: + pushl $0 +80106165: 6a 00 push $0x0 + pushl $62 +80106167: 6a 3e push $0x3e + jmp alltraps +80106169: e9 e0 f8 ff ff jmp 80105a4e + +8010616e : +.globl vector63 +vector63: + pushl $0 +8010616e: 6a 00 push $0x0 + pushl $63 +80106170: 6a 3f push $0x3f + jmp alltraps +80106172: e9 d7 f8 ff ff jmp 80105a4e + +80106177 : +.globl vector64 +vector64: + pushl $0 +80106177: 6a 00 push $0x0 + pushl $64 +80106179: 6a 40 push $0x40 + jmp alltraps +8010617b: e9 ce f8 ff ff jmp 80105a4e + +80106180 : +.globl vector65 +vector65: + pushl $0 +80106180: 6a 00 push $0x0 + pushl $65 +80106182: 6a 41 push $0x41 + jmp alltraps +80106184: e9 c5 f8 ff ff jmp 80105a4e + +80106189 : +.globl vector66 +vector66: + pushl $0 +80106189: 6a 00 push $0x0 + pushl $66 +8010618b: 6a 42 push $0x42 + jmp alltraps +8010618d: e9 bc f8 ff ff jmp 80105a4e + +80106192 : +.globl vector67 +vector67: + pushl $0 +80106192: 6a 00 push $0x0 + pushl $67 +80106194: 6a 43 push $0x43 + jmp alltraps +80106196: e9 b3 f8 ff ff jmp 80105a4e + +8010619b : +.globl vector68 +vector68: + pushl $0 +8010619b: 6a 00 push $0x0 + pushl $68 +8010619d: 6a 44 push $0x44 + jmp alltraps +8010619f: e9 aa f8 ff ff jmp 80105a4e + +801061a4 : +.globl vector69 +vector69: + pushl $0 +801061a4: 6a 00 push $0x0 + pushl $69 +801061a6: 6a 45 push $0x45 + jmp alltraps +801061a8: e9 a1 f8 ff ff jmp 80105a4e + +801061ad : +.globl vector70 +vector70: + pushl $0 +801061ad: 6a 00 push $0x0 + pushl $70 +801061af: 6a 46 push $0x46 + jmp alltraps +801061b1: e9 98 f8 ff ff jmp 80105a4e + +801061b6 : +.globl vector71 +vector71: + pushl $0 +801061b6: 6a 00 push $0x0 + pushl $71 +801061b8: 6a 47 push $0x47 + jmp alltraps +801061ba: e9 8f f8 ff ff jmp 80105a4e + +801061bf : +.globl vector72 +vector72: + pushl $0 +801061bf: 6a 00 push $0x0 + pushl $72 +801061c1: 6a 48 push $0x48 + jmp alltraps +801061c3: e9 86 f8 ff ff jmp 80105a4e + +801061c8 : +.globl vector73 +vector73: + pushl $0 +801061c8: 6a 00 push $0x0 + pushl $73 +801061ca: 6a 49 push $0x49 + jmp alltraps +801061cc: e9 7d f8 ff ff jmp 80105a4e + +801061d1 : +.globl vector74 +vector74: + pushl $0 +801061d1: 6a 00 push $0x0 + pushl $74 +801061d3: 6a 4a push $0x4a + jmp alltraps +801061d5: e9 74 f8 ff ff jmp 80105a4e + +801061da : +.globl vector75 +vector75: + pushl $0 +801061da: 6a 00 push $0x0 + pushl $75 +801061dc: 6a 4b push $0x4b + jmp alltraps +801061de: e9 6b f8 ff ff jmp 80105a4e + +801061e3 : +.globl vector76 +vector76: + pushl $0 +801061e3: 6a 00 push $0x0 + pushl $76 +801061e5: 6a 4c push $0x4c + jmp alltraps +801061e7: e9 62 f8 ff ff jmp 80105a4e + +801061ec : +.globl vector77 +vector77: + pushl $0 +801061ec: 6a 00 push $0x0 + pushl $77 +801061ee: 6a 4d push $0x4d + jmp alltraps +801061f0: e9 59 f8 ff ff jmp 80105a4e + +801061f5 : +.globl vector78 +vector78: + pushl $0 +801061f5: 6a 00 push $0x0 + pushl $78 +801061f7: 6a 4e push $0x4e + jmp alltraps +801061f9: e9 50 f8 ff ff jmp 80105a4e + +801061fe : +.globl vector79 +vector79: + pushl $0 +801061fe: 6a 00 push $0x0 + pushl $79 +80106200: 6a 4f push $0x4f + jmp alltraps +80106202: e9 47 f8 ff ff jmp 80105a4e + +80106207 : +.globl vector80 +vector80: + pushl $0 +80106207: 6a 00 push $0x0 + pushl $80 +80106209: 6a 50 push $0x50 + jmp alltraps +8010620b: e9 3e f8 ff ff jmp 80105a4e + +80106210 : +.globl vector81 +vector81: + pushl $0 +80106210: 6a 00 push $0x0 + pushl $81 +80106212: 6a 51 push $0x51 + jmp alltraps +80106214: e9 35 f8 ff ff jmp 80105a4e + +80106219 : +.globl vector82 +vector82: + pushl $0 +80106219: 6a 00 push $0x0 + pushl $82 +8010621b: 6a 52 push $0x52 + jmp alltraps +8010621d: e9 2c f8 ff ff jmp 80105a4e + +80106222 : +.globl vector83 +vector83: + pushl $0 +80106222: 6a 00 push $0x0 + pushl $83 +80106224: 6a 53 push $0x53 + jmp alltraps +80106226: e9 23 f8 ff ff jmp 80105a4e + +8010622b : +.globl vector84 +vector84: + pushl $0 +8010622b: 6a 00 push $0x0 + pushl $84 +8010622d: 6a 54 push $0x54 + jmp alltraps +8010622f: e9 1a f8 ff ff jmp 80105a4e + +80106234 : +.globl vector85 +vector85: + pushl $0 +80106234: 6a 00 push $0x0 + pushl $85 +80106236: 6a 55 push $0x55 + jmp alltraps +80106238: e9 11 f8 ff ff jmp 80105a4e + +8010623d : +.globl vector86 +vector86: + pushl $0 +8010623d: 6a 00 push $0x0 + pushl $86 +8010623f: 6a 56 push $0x56 + jmp alltraps +80106241: e9 08 f8 ff ff jmp 80105a4e + +80106246 : +.globl vector87 +vector87: + pushl $0 +80106246: 6a 00 push $0x0 + pushl $87 +80106248: 6a 57 push $0x57 + jmp alltraps +8010624a: e9 ff f7 ff ff jmp 80105a4e + +8010624f : +.globl vector88 +vector88: + pushl $0 +8010624f: 6a 00 push $0x0 + pushl $88 +80106251: 6a 58 push $0x58 + jmp alltraps +80106253: e9 f6 f7 ff ff jmp 80105a4e + +80106258 : +.globl vector89 +vector89: + pushl $0 +80106258: 6a 00 push $0x0 + pushl $89 +8010625a: 6a 59 push $0x59 + jmp alltraps +8010625c: e9 ed f7 ff ff jmp 80105a4e + +80106261 : +.globl vector90 +vector90: + pushl $0 +80106261: 6a 00 push $0x0 + pushl $90 +80106263: 6a 5a push $0x5a + jmp alltraps +80106265: e9 e4 f7 ff ff jmp 80105a4e + +8010626a : +.globl vector91 +vector91: + pushl $0 +8010626a: 6a 00 push $0x0 + pushl $91 +8010626c: 6a 5b push $0x5b + jmp alltraps +8010626e: e9 db f7 ff ff jmp 80105a4e + +80106273 : +.globl vector92 +vector92: + pushl $0 +80106273: 6a 00 push $0x0 + pushl $92 +80106275: 6a 5c push $0x5c + jmp alltraps +80106277: e9 d2 f7 ff ff jmp 80105a4e + +8010627c : +.globl vector93 +vector93: + pushl $0 +8010627c: 6a 00 push $0x0 + pushl $93 +8010627e: 6a 5d push $0x5d + jmp alltraps +80106280: e9 c9 f7 ff ff jmp 80105a4e + +80106285 : +.globl vector94 +vector94: + pushl $0 +80106285: 6a 00 push $0x0 + pushl $94 +80106287: 6a 5e push $0x5e + jmp alltraps +80106289: e9 c0 f7 ff ff jmp 80105a4e + +8010628e : +.globl vector95 +vector95: + pushl $0 +8010628e: 6a 00 push $0x0 + pushl $95 +80106290: 6a 5f push $0x5f + jmp alltraps +80106292: e9 b7 f7 ff ff jmp 80105a4e + +80106297 : +.globl vector96 +vector96: + pushl $0 +80106297: 6a 00 push $0x0 + pushl $96 +80106299: 6a 60 push $0x60 + jmp alltraps +8010629b: e9 ae f7 ff ff jmp 80105a4e + +801062a0 : +.globl vector97 +vector97: + pushl $0 +801062a0: 6a 00 push $0x0 + pushl $97 +801062a2: 6a 61 push $0x61 + jmp alltraps +801062a4: e9 a5 f7 ff ff jmp 80105a4e + +801062a9 : +.globl vector98 +vector98: + pushl $0 +801062a9: 6a 00 push $0x0 + pushl $98 +801062ab: 6a 62 push $0x62 + jmp alltraps +801062ad: e9 9c f7 ff ff jmp 80105a4e + +801062b2 : +.globl vector99 +vector99: + pushl $0 +801062b2: 6a 00 push $0x0 + pushl $99 +801062b4: 6a 63 push $0x63 + jmp alltraps +801062b6: e9 93 f7 ff ff jmp 80105a4e + +801062bb : +.globl vector100 +vector100: + pushl $0 +801062bb: 6a 00 push $0x0 + pushl $100 +801062bd: 6a 64 push $0x64 + jmp alltraps +801062bf: e9 8a f7 ff ff jmp 80105a4e + +801062c4 : +.globl vector101 +vector101: + pushl $0 +801062c4: 6a 00 push $0x0 + pushl $101 +801062c6: 6a 65 push $0x65 + jmp alltraps +801062c8: e9 81 f7 ff ff jmp 80105a4e + +801062cd : +.globl vector102 +vector102: + pushl $0 +801062cd: 6a 00 push $0x0 + pushl $102 +801062cf: 6a 66 push $0x66 + jmp alltraps +801062d1: e9 78 f7 ff ff jmp 80105a4e + +801062d6 : +.globl vector103 +vector103: + pushl $0 +801062d6: 6a 00 push $0x0 + pushl $103 +801062d8: 6a 67 push $0x67 + jmp alltraps +801062da: e9 6f f7 ff ff jmp 80105a4e + +801062df : +.globl vector104 +vector104: + pushl $0 +801062df: 6a 00 push $0x0 + pushl $104 +801062e1: 6a 68 push $0x68 + jmp alltraps +801062e3: e9 66 f7 ff ff jmp 80105a4e + +801062e8 : +.globl vector105 +vector105: + pushl $0 +801062e8: 6a 00 push $0x0 + pushl $105 +801062ea: 6a 69 push $0x69 + jmp alltraps +801062ec: e9 5d f7 ff ff jmp 80105a4e + +801062f1 : +.globl vector106 +vector106: + pushl $0 +801062f1: 6a 00 push $0x0 + pushl $106 +801062f3: 6a 6a push $0x6a + jmp alltraps +801062f5: e9 54 f7 ff ff jmp 80105a4e + +801062fa : +.globl vector107 +vector107: + pushl $0 +801062fa: 6a 00 push $0x0 + pushl $107 +801062fc: 6a 6b push $0x6b + jmp alltraps +801062fe: e9 4b f7 ff ff jmp 80105a4e + +80106303 : +.globl vector108 +vector108: + pushl $0 +80106303: 6a 00 push $0x0 + pushl $108 +80106305: 6a 6c push $0x6c + jmp alltraps +80106307: e9 42 f7 ff ff jmp 80105a4e + +8010630c : +.globl vector109 +vector109: + pushl $0 +8010630c: 6a 00 push $0x0 + pushl $109 +8010630e: 6a 6d push $0x6d + jmp alltraps +80106310: e9 39 f7 ff ff jmp 80105a4e + +80106315 : +.globl vector110 +vector110: + pushl $0 +80106315: 6a 00 push $0x0 + pushl $110 +80106317: 6a 6e push $0x6e + jmp alltraps +80106319: e9 30 f7 ff ff jmp 80105a4e + +8010631e : +.globl vector111 +vector111: + pushl $0 +8010631e: 6a 00 push $0x0 + pushl $111 +80106320: 6a 6f push $0x6f + jmp alltraps +80106322: e9 27 f7 ff ff jmp 80105a4e + +80106327 : +.globl vector112 +vector112: + pushl $0 +80106327: 6a 00 push $0x0 + pushl $112 +80106329: 6a 70 push $0x70 + jmp alltraps +8010632b: e9 1e f7 ff ff jmp 80105a4e + +80106330 : +.globl vector113 +vector113: + pushl $0 +80106330: 6a 00 push $0x0 + pushl $113 +80106332: 6a 71 push $0x71 + jmp alltraps +80106334: e9 15 f7 ff ff jmp 80105a4e + +80106339 : +.globl vector114 +vector114: + pushl $0 +80106339: 6a 00 push $0x0 + pushl $114 +8010633b: 6a 72 push $0x72 + jmp alltraps +8010633d: e9 0c f7 ff ff jmp 80105a4e + +80106342 : +.globl vector115 +vector115: + pushl $0 +80106342: 6a 00 push $0x0 + pushl $115 +80106344: 6a 73 push $0x73 + jmp alltraps +80106346: e9 03 f7 ff ff jmp 80105a4e + +8010634b : +.globl vector116 +vector116: + pushl $0 +8010634b: 6a 00 push $0x0 + pushl $116 +8010634d: 6a 74 push $0x74 + jmp alltraps +8010634f: e9 fa f6 ff ff jmp 80105a4e + +80106354 : +.globl vector117 +vector117: + pushl $0 +80106354: 6a 00 push $0x0 + pushl $117 +80106356: 6a 75 push $0x75 + jmp alltraps +80106358: e9 f1 f6 ff ff jmp 80105a4e + +8010635d : +.globl vector118 +vector118: + pushl $0 +8010635d: 6a 00 push $0x0 + pushl $118 +8010635f: 6a 76 push $0x76 + jmp alltraps +80106361: e9 e8 f6 ff ff jmp 80105a4e + +80106366 : +.globl vector119 +vector119: + pushl $0 +80106366: 6a 00 push $0x0 + pushl $119 +80106368: 6a 77 push $0x77 + jmp alltraps +8010636a: e9 df f6 ff ff jmp 80105a4e + +8010636f : +.globl vector120 +vector120: + pushl $0 +8010636f: 6a 00 push $0x0 + pushl $120 +80106371: 6a 78 push $0x78 + jmp alltraps +80106373: e9 d6 f6 ff ff jmp 80105a4e + +80106378 : +.globl vector121 +vector121: + pushl $0 +80106378: 6a 00 push $0x0 + pushl $121 +8010637a: 6a 79 push $0x79 + jmp alltraps +8010637c: e9 cd f6 ff ff jmp 80105a4e + +80106381 : +.globl vector122 +vector122: + pushl $0 +80106381: 6a 00 push $0x0 + pushl $122 +80106383: 6a 7a push $0x7a + jmp alltraps +80106385: e9 c4 f6 ff ff jmp 80105a4e + +8010638a : +.globl vector123 +vector123: + pushl $0 +8010638a: 6a 00 push $0x0 + pushl $123 +8010638c: 6a 7b push $0x7b + jmp alltraps +8010638e: e9 bb f6 ff ff jmp 80105a4e + +80106393 : +.globl vector124 +vector124: + pushl $0 +80106393: 6a 00 push $0x0 + pushl $124 +80106395: 6a 7c push $0x7c + jmp alltraps +80106397: e9 b2 f6 ff ff jmp 80105a4e + +8010639c : +.globl vector125 +vector125: + pushl $0 +8010639c: 6a 00 push $0x0 + pushl $125 +8010639e: 6a 7d push $0x7d + jmp alltraps +801063a0: e9 a9 f6 ff ff jmp 80105a4e + +801063a5 : +.globl vector126 +vector126: + pushl $0 +801063a5: 6a 00 push $0x0 + pushl $126 +801063a7: 6a 7e push $0x7e + jmp alltraps +801063a9: e9 a0 f6 ff ff jmp 80105a4e + +801063ae : +.globl vector127 +vector127: + pushl $0 +801063ae: 6a 00 push $0x0 + pushl $127 +801063b0: 6a 7f push $0x7f + jmp alltraps +801063b2: e9 97 f6 ff ff jmp 80105a4e + +801063b7 : +.globl vector128 +vector128: + pushl $0 +801063b7: 6a 00 push $0x0 + pushl $128 +801063b9: 68 80 00 00 00 push $0x80 + jmp alltraps +801063be: e9 8b f6 ff ff jmp 80105a4e + +801063c3 : +.globl vector129 +vector129: + pushl $0 +801063c3: 6a 00 push $0x0 + pushl $129 +801063c5: 68 81 00 00 00 push $0x81 + jmp alltraps +801063ca: e9 7f f6 ff ff jmp 80105a4e + +801063cf : +.globl vector130 +vector130: + pushl $0 +801063cf: 6a 00 push $0x0 + pushl $130 +801063d1: 68 82 00 00 00 push $0x82 + jmp alltraps +801063d6: e9 73 f6 ff ff jmp 80105a4e + +801063db : +.globl vector131 +vector131: + pushl $0 +801063db: 6a 00 push $0x0 + pushl $131 +801063dd: 68 83 00 00 00 push $0x83 + jmp alltraps +801063e2: e9 67 f6 ff ff jmp 80105a4e + +801063e7 : +.globl vector132 +vector132: + pushl $0 +801063e7: 6a 00 push $0x0 + pushl $132 +801063e9: 68 84 00 00 00 push $0x84 + jmp alltraps +801063ee: e9 5b f6 ff ff jmp 80105a4e + +801063f3 : +.globl vector133 +vector133: + pushl $0 +801063f3: 6a 00 push $0x0 + pushl $133 +801063f5: 68 85 00 00 00 push $0x85 + jmp alltraps +801063fa: e9 4f f6 ff ff jmp 80105a4e + +801063ff : +.globl vector134 +vector134: + pushl $0 +801063ff: 6a 00 push $0x0 + pushl $134 +80106401: 68 86 00 00 00 push $0x86 + jmp alltraps +80106406: e9 43 f6 ff ff jmp 80105a4e + +8010640b : +.globl vector135 +vector135: + pushl $0 +8010640b: 6a 00 push $0x0 + pushl $135 +8010640d: 68 87 00 00 00 push $0x87 + jmp alltraps +80106412: e9 37 f6 ff ff jmp 80105a4e + +80106417 : +.globl vector136 +vector136: + pushl $0 +80106417: 6a 00 push $0x0 + pushl $136 +80106419: 68 88 00 00 00 push $0x88 + jmp alltraps +8010641e: e9 2b f6 ff ff jmp 80105a4e + +80106423 : +.globl vector137 +vector137: + pushl $0 +80106423: 6a 00 push $0x0 + pushl $137 +80106425: 68 89 00 00 00 push $0x89 + jmp alltraps +8010642a: e9 1f f6 ff ff jmp 80105a4e + +8010642f : +.globl vector138 +vector138: + pushl $0 +8010642f: 6a 00 push $0x0 + pushl $138 +80106431: 68 8a 00 00 00 push $0x8a + jmp alltraps +80106436: e9 13 f6 ff ff jmp 80105a4e + +8010643b : +.globl vector139 +vector139: + pushl $0 +8010643b: 6a 00 push $0x0 + pushl $139 +8010643d: 68 8b 00 00 00 push $0x8b + jmp alltraps +80106442: e9 07 f6 ff ff jmp 80105a4e + +80106447 : +.globl vector140 +vector140: + pushl $0 +80106447: 6a 00 push $0x0 + pushl $140 +80106449: 68 8c 00 00 00 push $0x8c + jmp alltraps +8010644e: e9 fb f5 ff ff jmp 80105a4e + +80106453 : +.globl vector141 +vector141: + pushl $0 +80106453: 6a 00 push $0x0 + pushl $141 +80106455: 68 8d 00 00 00 push $0x8d + jmp alltraps +8010645a: e9 ef f5 ff ff jmp 80105a4e + +8010645f : +.globl vector142 +vector142: + pushl $0 +8010645f: 6a 00 push $0x0 + pushl $142 +80106461: 68 8e 00 00 00 push $0x8e + jmp alltraps +80106466: e9 e3 f5 ff ff jmp 80105a4e + +8010646b : +.globl vector143 +vector143: + pushl $0 +8010646b: 6a 00 push $0x0 + pushl $143 +8010646d: 68 8f 00 00 00 push $0x8f + jmp alltraps +80106472: e9 d7 f5 ff ff jmp 80105a4e + +80106477 : +.globl vector144 +vector144: + pushl $0 +80106477: 6a 00 push $0x0 + pushl $144 +80106479: 68 90 00 00 00 push $0x90 + jmp alltraps +8010647e: e9 cb f5 ff ff jmp 80105a4e + +80106483 : +.globl vector145 +vector145: + pushl $0 +80106483: 6a 00 push $0x0 + pushl $145 +80106485: 68 91 00 00 00 push $0x91 + jmp alltraps +8010648a: e9 bf f5 ff ff jmp 80105a4e + +8010648f : +.globl vector146 +vector146: + pushl $0 +8010648f: 6a 00 push $0x0 + pushl $146 +80106491: 68 92 00 00 00 push $0x92 + jmp alltraps +80106496: e9 b3 f5 ff ff jmp 80105a4e + +8010649b : +.globl vector147 +vector147: + pushl $0 +8010649b: 6a 00 push $0x0 + pushl $147 +8010649d: 68 93 00 00 00 push $0x93 + jmp alltraps +801064a2: e9 a7 f5 ff ff jmp 80105a4e + +801064a7 : +.globl vector148 +vector148: + pushl $0 +801064a7: 6a 00 push $0x0 + pushl $148 +801064a9: 68 94 00 00 00 push $0x94 + jmp alltraps +801064ae: e9 9b f5 ff ff jmp 80105a4e + +801064b3 : +.globl vector149 +vector149: + pushl $0 +801064b3: 6a 00 push $0x0 + pushl $149 +801064b5: 68 95 00 00 00 push $0x95 + jmp alltraps +801064ba: e9 8f f5 ff ff jmp 80105a4e + +801064bf : +.globl vector150 +vector150: + pushl $0 +801064bf: 6a 00 push $0x0 + pushl $150 +801064c1: 68 96 00 00 00 push $0x96 + jmp alltraps +801064c6: e9 83 f5 ff ff jmp 80105a4e + +801064cb : +.globl vector151 +vector151: + pushl $0 +801064cb: 6a 00 push $0x0 + pushl $151 +801064cd: 68 97 00 00 00 push $0x97 + jmp alltraps +801064d2: e9 77 f5 ff ff jmp 80105a4e + +801064d7 : +.globl vector152 +vector152: + pushl $0 +801064d7: 6a 00 push $0x0 + pushl $152 +801064d9: 68 98 00 00 00 push $0x98 + jmp alltraps +801064de: e9 6b f5 ff ff jmp 80105a4e + +801064e3 : +.globl vector153 +vector153: + pushl $0 +801064e3: 6a 00 push $0x0 + pushl $153 +801064e5: 68 99 00 00 00 push $0x99 + jmp alltraps +801064ea: e9 5f f5 ff ff jmp 80105a4e + +801064ef : +.globl vector154 +vector154: + pushl $0 +801064ef: 6a 00 push $0x0 + pushl $154 +801064f1: 68 9a 00 00 00 push $0x9a + jmp alltraps +801064f6: e9 53 f5 ff ff jmp 80105a4e + +801064fb : +.globl vector155 +vector155: + pushl $0 +801064fb: 6a 00 push $0x0 + pushl $155 +801064fd: 68 9b 00 00 00 push $0x9b + jmp alltraps +80106502: e9 47 f5 ff ff jmp 80105a4e + +80106507 : +.globl vector156 +vector156: + pushl $0 +80106507: 6a 00 push $0x0 + pushl $156 +80106509: 68 9c 00 00 00 push $0x9c + jmp alltraps +8010650e: e9 3b f5 ff ff jmp 80105a4e + +80106513 : +.globl vector157 +vector157: + pushl $0 +80106513: 6a 00 push $0x0 + pushl $157 +80106515: 68 9d 00 00 00 push $0x9d + jmp alltraps +8010651a: e9 2f f5 ff ff jmp 80105a4e + +8010651f : +.globl vector158 +vector158: + pushl $0 +8010651f: 6a 00 push $0x0 + pushl $158 +80106521: 68 9e 00 00 00 push $0x9e + jmp alltraps +80106526: e9 23 f5 ff ff jmp 80105a4e + +8010652b : +.globl vector159 +vector159: + pushl $0 +8010652b: 6a 00 push $0x0 + pushl $159 +8010652d: 68 9f 00 00 00 push $0x9f + jmp alltraps +80106532: e9 17 f5 ff ff jmp 80105a4e + +80106537 : +.globl vector160 +vector160: + pushl $0 +80106537: 6a 00 push $0x0 + pushl $160 +80106539: 68 a0 00 00 00 push $0xa0 + jmp alltraps +8010653e: e9 0b f5 ff ff jmp 80105a4e + +80106543 : +.globl vector161 +vector161: + pushl $0 +80106543: 6a 00 push $0x0 + pushl $161 +80106545: 68 a1 00 00 00 push $0xa1 + jmp alltraps +8010654a: e9 ff f4 ff ff jmp 80105a4e + +8010654f : +.globl vector162 +vector162: + pushl $0 +8010654f: 6a 00 push $0x0 + pushl $162 +80106551: 68 a2 00 00 00 push $0xa2 + jmp alltraps +80106556: e9 f3 f4 ff ff jmp 80105a4e + +8010655b : +.globl vector163 +vector163: + pushl $0 +8010655b: 6a 00 push $0x0 + pushl $163 +8010655d: 68 a3 00 00 00 push $0xa3 + jmp alltraps +80106562: e9 e7 f4 ff ff jmp 80105a4e + +80106567 : +.globl vector164 +vector164: + pushl $0 +80106567: 6a 00 push $0x0 + pushl $164 +80106569: 68 a4 00 00 00 push $0xa4 + jmp alltraps +8010656e: e9 db f4 ff ff jmp 80105a4e + +80106573 : +.globl vector165 +vector165: + pushl $0 +80106573: 6a 00 push $0x0 + pushl $165 +80106575: 68 a5 00 00 00 push $0xa5 + jmp alltraps +8010657a: e9 cf f4 ff ff jmp 80105a4e + +8010657f : +.globl vector166 +vector166: + pushl $0 +8010657f: 6a 00 push $0x0 + pushl $166 +80106581: 68 a6 00 00 00 push $0xa6 + jmp alltraps +80106586: e9 c3 f4 ff ff jmp 80105a4e + +8010658b : +.globl vector167 +vector167: + pushl $0 +8010658b: 6a 00 push $0x0 + pushl $167 +8010658d: 68 a7 00 00 00 push $0xa7 + jmp alltraps +80106592: e9 b7 f4 ff ff jmp 80105a4e + +80106597 : +.globl vector168 +vector168: + pushl $0 +80106597: 6a 00 push $0x0 + pushl $168 +80106599: 68 a8 00 00 00 push $0xa8 + jmp alltraps +8010659e: e9 ab f4 ff ff jmp 80105a4e + +801065a3 : +.globl vector169 +vector169: + pushl $0 +801065a3: 6a 00 push $0x0 + pushl $169 +801065a5: 68 a9 00 00 00 push $0xa9 + jmp alltraps +801065aa: e9 9f f4 ff ff jmp 80105a4e + +801065af : +.globl vector170 +vector170: + pushl $0 +801065af: 6a 00 push $0x0 + pushl $170 +801065b1: 68 aa 00 00 00 push $0xaa + jmp alltraps +801065b6: e9 93 f4 ff ff jmp 80105a4e + +801065bb : +.globl vector171 +vector171: + pushl $0 +801065bb: 6a 00 push $0x0 + pushl $171 +801065bd: 68 ab 00 00 00 push $0xab + jmp alltraps +801065c2: e9 87 f4 ff ff jmp 80105a4e + +801065c7 : +.globl vector172 +vector172: + pushl $0 +801065c7: 6a 00 push $0x0 + pushl $172 +801065c9: 68 ac 00 00 00 push $0xac + jmp alltraps +801065ce: e9 7b f4 ff ff jmp 80105a4e + +801065d3 : +.globl vector173 +vector173: + pushl $0 +801065d3: 6a 00 push $0x0 + pushl $173 +801065d5: 68 ad 00 00 00 push $0xad + jmp alltraps +801065da: e9 6f f4 ff ff jmp 80105a4e + +801065df : +.globl vector174 +vector174: + pushl $0 +801065df: 6a 00 push $0x0 + pushl $174 +801065e1: 68 ae 00 00 00 push $0xae + jmp alltraps +801065e6: e9 63 f4 ff ff jmp 80105a4e + +801065eb : +.globl vector175 +vector175: + pushl $0 +801065eb: 6a 00 push $0x0 + pushl $175 +801065ed: 68 af 00 00 00 push $0xaf + jmp alltraps +801065f2: e9 57 f4 ff ff jmp 80105a4e + +801065f7 : +.globl vector176 +vector176: + pushl $0 +801065f7: 6a 00 push $0x0 + pushl $176 +801065f9: 68 b0 00 00 00 push $0xb0 + jmp alltraps +801065fe: e9 4b f4 ff ff jmp 80105a4e + +80106603 : +.globl vector177 +vector177: + pushl $0 +80106603: 6a 00 push $0x0 + pushl $177 +80106605: 68 b1 00 00 00 push $0xb1 + jmp alltraps +8010660a: e9 3f f4 ff ff jmp 80105a4e + +8010660f : +.globl vector178 +vector178: + pushl $0 +8010660f: 6a 00 push $0x0 + pushl $178 +80106611: 68 b2 00 00 00 push $0xb2 + jmp alltraps +80106616: e9 33 f4 ff ff jmp 80105a4e + +8010661b : +.globl vector179 +vector179: + pushl $0 +8010661b: 6a 00 push $0x0 + pushl $179 +8010661d: 68 b3 00 00 00 push $0xb3 + jmp alltraps +80106622: e9 27 f4 ff ff jmp 80105a4e + +80106627 : +.globl vector180 +vector180: + pushl $0 +80106627: 6a 00 push $0x0 + pushl $180 +80106629: 68 b4 00 00 00 push $0xb4 + jmp alltraps +8010662e: e9 1b f4 ff ff jmp 80105a4e + +80106633 : +.globl vector181 +vector181: + pushl $0 +80106633: 6a 00 push $0x0 + pushl $181 +80106635: 68 b5 00 00 00 push $0xb5 + jmp alltraps +8010663a: e9 0f f4 ff ff jmp 80105a4e + +8010663f : +.globl vector182 +vector182: + pushl $0 +8010663f: 6a 00 push $0x0 + pushl $182 +80106641: 68 b6 00 00 00 push $0xb6 + jmp alltraps +80106646: e9 03 f4 ff ff jmp 80105a4e + +8010664b : +.globl vector183 +vector183: + pushl $0 +8010664b: 6a 00 push $0x0 + pushl $183 +8010664d: 68 b7 00 00 00 push $0xb7 + jmp alltraps +80106652: e9 f7 f3 ff ff jmp 80105a4e + +80106657 : +.globl vector184 +vector184: + pushl $0 +80106657: 6a 00 push $0x0 + pushl $184 +80106659: 68 b8 00 00 00 push $0xb8 + jmp alltraps +8010665e: e9 eb f3 ff ff jmp 80105a4e + +80106663 : +.globl vector185 +vector185: + pushl $0 +80106663: 6a 00 push $0x0 + pushl $185 +80106665: 68 b9 00 00 00 push $0xb9 + jmp alltraps +8010666a: e9 df f3 ff ff jmp 80105a4e + +8010666f : +.globl vector186 +vector186: + pushl $0 +8010666f: 6a 00 push $0x0 + pushl $186 +80106671: 68 ba 00 00 00 push $0xba + jmp alltraps +80106676: e9 d3 f3 ff ff jmp 80105a4e + +8010667b : +.globl vector187 +vector187: + pushl $0 +8010667b: 6a 00 push $0x0 + pushl $187 +8010667d: 68 bb 00 00 00 push $0xbb + jmp alltraps +80106682: e9 c7 f3 ff ff jmp 80105a4e + +80106687 : +.globl vector188 +vector188: + pushl $0 +80106687: 6a 00 push $0x0 + pushl $188 +80106689: 68 bc 00 00 00 push $0xbc + jmp alltraps +8010668e: e9 bb f3 ff ff jmp 80105a4e + +80106693 : +.globl vector189 +vector189: + pushl $0 +80106693: 6a 00 push $0x0 + pushl $189 +80106695: 68 bd 00 00 00 push $0xbd + jmp alltraps +8010669a: e9 af f3 ff ff jmp 80105a4e + +8010669f : +.globl vector190 +vector190: + pushl $0 +8010669f: 6a 00 push $0x0 + pushl $190 +801066a1: 68 be 00 00 00 push $0xbe + jmp alltraps +801066a6: e9 a3 f3 ff ff jmp 80105a4e + +801066ab : +.globl vector191 +vector191: + pushl $0 +801066ab: 6a 00 push $0x0 + pushl $191 +801066ad: 68 bf 00 00 00 push $0xbf + jmp alltraps +801066b2: e9 97 f3 ff ff jmp 80105a4e + +801066b7 : +.globl vector192 +vector192: + pushl $0 +801066b7: 6a 00 push $0x0 + pushl $192 +801066b9: 68 c0 00 00 00 push $0xc0 + jmp alltraps +801066be: e9 8b f3 ff ff jmp 80105a4e + +801066c3 : +.globl vector193 +vector193: + pushl $0 +801066c3: 6a 00 push $0x0 + pushl $193 +801066c5: 68 c1 00 00 00 push $0xc1 + jmp alltraps +801066ca: e9 7f f3 ff ff jmp 80105a4e + +801066cf : +.globl vector194 +vector194: + pushl $0 +801066cf: 6a 00 push $0x0 + pushl $194 +801066d1: 68 c2 00 00 00 push $0xc2 + jmp alltraps +801066d6: e9 73 f3 ff ff jmp 80105a4e + +801066db : +.globl vector195 +vector195: + pushl $0 +801066db: 6a 00 push $0x0 + pushl $195 +801066dd: 68 c3 00 00 00 push $0xc3 + jmp alltraps +801066e2: e9 67 f3 ff ff jmp 80105a4e + +801066e7 : +.globl vector196 +vector196: + pushl $0 +801066e7: 6a 00 push $0x0 + pushl $196 +801066e9: 68 c4 00 00 00 push $0xc4 + jmp alltraps +801066ee: e9 5b f3 ff ff jmp 80105a4e + +801066f3 : +.globl vector197 +vector197: + pushl $0 +801066f3: 6a 00 push $0x0 + pushl $197 +801066f5: 68 c5 00 00 00 push $0xc5 + jmp alltraps +801066fa: e9 4f f3 ff ff jmp 80105a4e + +801066ff : +.globl vector198 +vector198: + pushl $0 +801066ff: 6a 00 push $0x0 + pushl $198 +80106701: 68 c6 00 00 00 push $0xc6 + jmp alltraps +80106706: e9 43 f3 ff ff jmp 80105a4e + +8010670b : +.globl vector199 +vector199: + pushl $0 +8010670b: 6a 00 push $0x0 + pushl $199 +8010670d: 68 c7 00 00 00 push $0xc7 + jmp alltraps +80106712: e9 37 f3 ff ff jmp 80105a4e + +80106717 : +.globl vector200 +vector200: + pushl $0 +80106717: 6a 00 push $0x0 + pushl $200 +80106719: 68 c8 00 00 00 push $0xc8 + jmp alltraps +8010671e: e9 2b f3 ff ff jmp 80105a4e + +80106723 : +.globl vector201 +vector201: + pushl $0 +80106723: 6a 00 push $0x0 + pushl $201 +80106725: 68 c9 00 00 00 push $0xc9 + jmp alltraps +8010672a: e9 1f f3 ff ff jmp 80105a4e + +8010672f : +.globl vector202 +vector202: + pushl $0 +8010672f: 6a 00 push $0x0 + pushl $202 +80106731: 68 ca 00 00 00 push $0xca + jmp alltraps +80106736: e9 13 f3 ff ff jmp 80105a4e + +8010673b : +.globl vector203 +vector203: + pushl $0 +8010673b: 6a 00 push $0x0 + pushl $203 +8010673d: 68 cb 00 00 00 push $0xcb + jmp alltraps +80106742: e9 07 f3 ff ff jmp 80105a4e + +80106747 : +.globl vector204 +vector204: + pushl $0 +80106747: 6a 00 push $0x0 + pushl $204 +80106749: 68 cc 00 00 00 push $0xcc + jmp alltraps +8010674e: e9 fb f2 ff ff jmp 80105a4e + +80106753 : +.globl vector205 +vector205: + pushl $0 +80106753: 6a 00 push $0x0 + pushl $205 +80106755: 68 cd 00 00 00 push $0xcd + jmp alltraps +8010675a: e9 ef f2 ff ff jmp 80105a4e + +8010675f : +.globl vector206 +vector206: + pushl $0 +8010675f: 6a 00 push $0x0 + pushl $206 +80106761: 68 ce 00 00 00 push $0xce + jmp alltraps +80106766: e9 e3 f2 ff ff jmp 80105a4e + +8010676b : +.globl vector207 +vector207: + pushl $0 +8010676b: 6a 00 push $0x0 + pushl $207 +8010676d: 68 cf 00 00 00 push $0xcf + jmp alltraps +80106772: e9 d7 f2 ff ff jmp 80105a4e + +80106777 : +.globl vector208 +vector208: + pushl $0 +80106777: 6a 00 push $0x0 + pushl $208 +80106779: 68 d0 00 00 00 push $0xd0 + jmp alltraps +8010677e: e9 cb f2 ff ff jmp 80105a4e + +80106783 : +.globl vector209 +vector209: + pushl $0 +80106783: 6a 00 push $0x0 + pushl $209 +80106785: 68 d1 00 00 00 push $0xd1 + jmp alltraps +8010678a: e9 bf f2 ff ff jmp 80105a4e + +8010678f : +.globl vector210 +vector210: + pushl $0 +8010678f: 6a 00 push $0x0 + pushl $210 +80106791: 68 d2 00 00 00 push $0xd2 + jmp alltraps +80106796: e9 b3 f2 ff ff jmp 80105a4e + +8010679b : +.globl vector211 +vector211: + pushl $0 +8010679b: 6a 00 push $0x0 + pushl $211 +8010679d: 68 d3 00 00 00 push $0xd3 + jmp alltraps +801067a2: e9 a7 f2 ff ff jmp 80105a4e + +801067a7 : +.globl vector212 +vector212: + pushl $0 +801067a7: 6a 00 push $0x0 + pushl $212 +801067a9: 68 d4 00 00 00 push $0xd4 + jmp alltraps +801067ae: e9 9b f2 ff ff jmp 80105a4e + +801067b3 : +.globl vector213 +vector213: + pushl $0 +801067b3: 6a 00 push $0x0 + pushl $213 +801067b5: 68 d5 00 00 00 push $0xd5 + jmp alltraps +801067ba: e9 8f f2 ff ff jmp 80105a4e + +801067bf : +.globl vector214 +vector214: + pushl $0 +801067bf: 6a 00 push $0x0 + pushl $214 +801067c1: 68 d6 00 00 00 push $0xd6 + jmp alltraps +801067c6: e9 83 f2 ff ff jmp 80105a4e + +801067cb : +.globl vector215 +vector215: + pushl $0 +801067cb: 6a 00 push $0x0 + pushl $215 +801067cd: 68 d7 00 00 00 push $0xd7 + jmp alltraps +801067d2: e9 77 f2 ff ff jmp 80105a4e + +801067d7 : +.globl vector216 +vector216: + pushl $0 +801067d7: 6a 00 push $0x0 + pushl $216 +801067d9: 68 d8 00 00 00 push $0xd8 + jmp alltraps +801067de: e9 6b f2 ff ff jmp 80105a4e + +801067e3 : +.globl vector217 +vector217: + pushl $0 +801067e3: 6a 00 push $0x0 + pushl $217 +801067e5: 68 d9 00 00 00 push $0xd9 + jmp alltraps +801067ea: e9 5f f2 ff ff jmp 80105a4e + +801067ef : +.globl vector218 +vector218: + pushl $0 +801067ef: 6a 00 push $0x0 + pushl $218 +801067f1: 68 da 00 00 00 push $0xda + jmp alltraps +801067f6: e9 53 f2 ff ff jmp 80105a4e + +801067fb : +.globl vector219 +vector219: + pushl $0 +801067fb: 6a 00 push $0x0 + pushl $219 +801067fd: 68 db 00 00 00 push $0xdb + jmp alltraps +80106802: e9 47 f2 ff ff jmp 80105a4e + +80106807 : +.globl vector220 +vector220: + pushl $0 +80106807: 6a 00 push $0x0 + pushl $220 +80106809: 68 dc 00 00 00 push $0xdc + jmp alltraps +8010680e: e9 3b f2 ff ff jmp 80105a4e + +80106813 : +.globl vector221 +vector221: + pushl $0 +80106813: 6a 00 push $0x0 + pushl $221 +80106815: 68 dd 00 00 00 push $0xdd + jmp alltraps +8010681a: e9 2f f2 ff ff jmp 80105a4e + +8010681f : +.globl vector222 +vector222: + pushl $0 +8010681f: 6a 00 push $0x0 + pushl $222 +80106821: 68 de 00 00 00 push $0xde + jmp alltraps +80106826: e9 23 f2 ff ff jmp 80105a4e + +8010682b : +.globl vector223 +vector223: + pushl $0 +8010682b: 6a 00 push $0x0 + pushl $223 +8010682d: 68 df 00 00 00 push $0xdf + jmp alltraps +80106832: e9 17 f2 ff ff jmp 80105a4e + +80106837 : +.globl vector224 +vector224: + pushl $0 +80106837: 6a 00 push $0x0 + pushl $224 +80106839: 68 e0 00 00 00 push $0xe0 + jmp alltraps +8010683e: e9 0b f2 ff ff jmp 80105a4e + +80106843 : +.globl vector225 +vector225: + pushl $0 +80106843: 6a 00 push $0x0 + pushl $225 +80106845: 68 e1 00 00 00 push $0xe1 + jmp alltraps +8010684a: e9 ff f1 ff ff jmp 80105a4e + +8010684f : +.globl vector226 +vector226: + pushl $0 +8010684f: 6a 00 push $0x0 + pushl $226 +80106851: 68 e2 00 00 00 push $0xe2 + jmp alltraps +80106856: e9 f3 f1 ff ff jmp 80105a4e + +8010685b : +.globl vector227 +vector227: + pushl $0 +8010685b: 6a 00 push $0x0 + pushl $227 +8010685d: 68 e3 00 00 00 push $0xe3 + jmp alltraps +80106862: e9 e7 f1 ff ff jmp 80105a4e + +80106867 : +.globl vector228 +vector228: + pushl $0 +80106867: 6a 00 push $0x0 + pushl $228 +80106869: 68 e4 00 00 00 push $0xe4 + jmp alltraps +8010686e: e9 db f1 ff ff jmp 80105a4e + +80106873 : +.globl vector229 +vector229: + pushl $0 +80106873: 6a 00 push $0x0 + pushl $229 +80106875: 68 e5 00 00 00 push $0xe5 + jmp alltraps +8010687a: e9 cf f1 ff ff jmp 80105a4e + +8010687f : +.globl vector230 +vector230: + pushl $0 +8010687f: 6a 00 push $0x0 + pushl $230 +80106881: 68 e6 00 00 00 push $0xe6 + jmp alltraps +80106886: e9 c3 f1 ff ff jmp 80105a4e + +8010688b : +.globl vector231 +vector231: + pushl $0 +8010688b: 6a 00 push $0x0 + pushl $231 +8010688d: 68 e7 00 00 00 push $0xe7 + jmp alltraps +80106892: e9 b7 f1 ff ff jmp 80105a4e + +80106897 : +.globl vector232 +vector232: + pushl $0 +80106897: 6a 00 push $0x0 + pushl $232 +80106899: 68 e8 00 00 00 push $0xe8 + jmp alltraps +8010689e: e9 ab f1 ff ff jmp 80105a4e + +801068a3 : +.globl vector233 +vector233: + pushl $0 +801068a3: 6a 00 push $0x0 + pushl $233 +801068a5: 68 e9 00 00 00 push $0xe9 + jmp alltraps +801068aa: e9 9f f1 ff ff jmp 80105a4e + +801068af : +.globl vector234 +vector234: + pushl $0 +801068af: 6a 00 push $0x0 + pushl $234 +801068b1: 68 ea 00 00 00 push $0xea + jmp alltraps +801068b6: e9 93 f1 ff ff jmp 80105a4e + +801068bb : +.globl vector235 +vector235: + pushl $0 +801068bb: 6a 00 push $0x0 + pushl $235 +801068bd: 68 eb 00 00 00 push $0xeb + jmp alltraps +801068c2: e9 87 f1 ff ff jmp 80105a4e + +801068c7 : +.globl vector236 +vector236: + pushl $0 +801068c7: 6a 00 push $0x0 + pushl $236 +801068c9: 68 ec 00 00 00 push $0xec + jmp alltraps +801068ce: e9 7b f1 ff ff jmp 80105a4e + +801068d3 : +.globl vector237 +vector237: + pushl $0 +801068d3: 6a 00 push $0x0 + pushl $237 +801068d5: 68 ed 00 00 00 push $0xed + jmp alltraps +801068da: e9 6f f1 ff ff jmp 80105a4e + +801068df : +.globl vector238 +vector238: + pushl $0 +801068df: 6a 00 push $0x0 + pushl $238 +801068e1: 68 ee 00 00 00 push $0xee + jmp alltraps +801068e6: e9 63 f1 ff ff jmp 80105a4e + +801068eb : +.globl vector239 +vector239: + pushl $0 +801068eb: 6a 00 push $0x0 + pushl $239 +801068ed: 68 ef 00 00 00 push $0xef + jmp alltraps +801068f2: e9 57 f1 ff ff jmp 80105a4e + +801068f7 : +.globl vector240 +vector240: + pushl $0 +801068f7: 6a 00 push $0x0 + pushl $240 +801068f9: 68 f0 00 00 00 push $0xf0 + jmp alltraps +801068fe: e9 4b f1 ff ff jmp 80105a4e + +80106903 : +.globl vector241 +vector241: + pushl $0 +80106903: 6a 00 push $0x0 + pushl $241 +80106905: 68 f1 00 00 00 push $0xf1 + jmp alltraps +8010690a: e9 3f f1 ff ff jmp 80105a4e + +8010690f : +.globl vector242 +vector242: + pushl $0 +8010690f: 6a 00 push $0x0 + pushl $242 +80106911: 68 f2 00 00 00 push $0xf2 + jmp alltraps +80106916: e9 33 f1 ff ff jmp 80105a4e + +8010691b : +.globl vector243 +vector243: + pushl $0 +8010691b: 6a 00 push $0x0 + pushl $243 +8010691d: 68 f3 00 00 00 push $0xf3 + jmp alltraps +80106922: e9 27 f1 ff ff jmp 80105a4e + +80106927 : +.globl vector244 +vector244: + pushl $0 +80106927: 6a 00 push $0x0 + pushl $244 +80106929: 68 f4 00 00 00 push $0xf4 + jmp alltraps +8010692e: e9 1b f1 ff ff jmp 80105a4e + +80106933 : +.globl vector245 +vector245: + pushl $0 +80106933: 6a 00 push $0x0 + pushl $245 +80106935: 68 f5 00 00 00 push $0xf5 + jmp alltraps +8010693a: e9 0f f1 ff ff jmp 80105a4e + +8010693f : +.globl vector246 +vector246: + pushl $0 +8010693f: 6a 00 push $0x0 + pushl $246 +80106941: 68 f6 00 00 00 push $0xf6 + jmp alltraps +80106946: e9 03 f1 ff ff jmp 80105a4e + +8010694b : +.globl vector247 +vector247: + pushl $0 +8010694b: 6a 00 push $0x0 + pushl $247 +8010694d: 68 f7 00 00 00 push $0xf7 + jmp alltraps +80106952: e9 f7 f0 ff ff jmp 80105a4e + +80106957 : +.globl vector248 +vector248: + pushl $0 +80106957: 6a 00 push $0x0 + pushl $248 +80106959: 68 f8 00 00 00 push $0xf8 + jmp alltraps +8010695e: e9 eb f0 ff ff jmp 80105a4e + +80106963 : +.globl vector249 +vector249: + pushl $0 +80106963: 6a 00 push $0x0 + pushl $249 +80106965: 68 f9 00 00 00 push $0xf9 + jmp alltraps +8010696a: e9 df f0 ff ff jmp 80105a4e + +8010696f : +.globl vector250 +vector250: + pushl $0 +8010696f: 6a 00 push $0x0 + pushl $250 +80106971: 68 fa 00 00 00 push $0xfa + jmp alltraps +80106976: e9 d3 f0 ff ff jmp 80105a4e + +8010697b : +.globl vector251 +vector251: + pushl $0 +8010697b: 6a 00 push $0x0 + pushl $251 +8010697d: 68 fb 00 00 00 push $0xfb + jmp alltraps +80106982: e9 c7 f0 ff ff jmp 80105a4e + +80106987 : +.globl vector252 +vector252: + pushl $0 +80106987: 6a 00 push $0x0 + pushl $252 +80106989: 68 fc 00 00 00 push $0xfc + jmp alltraps +8010698e: e9 bb f0 ff ff jmp 80105a4e + +80106993 : +.globl vector253 +vector253: + pushl $0 +80106993: 6a 00 push $0x0 + pushl $253 +80106995: 68 fd 00 00 00 push $0xfd + jmp alltraps +8010699a: e9 af f0 ff ff jmp 80105a4e + +8010699f : +.globl vector254 +vector254: + pushl $0 +8010699f: 6a 00 push $0x0 + pushl $254 +801069a1: 68 fe 00 00 00 push $0xfe + jmp alltraps +801069a6: e9 a3 f0 ff ff jmp 80105a4e + +801069ab : +.globl vector255 +vector255: + pushl $0 +801069ab: 6a 00 push $0x0 + pushl $255 +801069ad: 68 ff 00 00 00 push $0xff + jmp alltraps +801069b2: e9 97 f0 ff ff jmp 80105a4e +801069b7: 66 90 xchg %ax,%ax +801069b9: 66 90 xchg %ax,%ax +801069bb: 66 90 xchg %ax,%ax +801069bd: 66 90 xchg %ax,%ax +801069bf: 90 nop + +801069c0 : + +// Deallocate user pages to bring the process size from oldsz to +// newsz. oldsz and newsz need not be page-aligned, nor does newsz +// need to be less than oldsz. oldsz can be larger than the actual +// process size. Returns the new process size. +int deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) { +801069c0: 55 push %ebp +801069c1: 89 e5 mov %esp,%ebp +801069c3: 57 push %edi +801069c4: 56 push %esi +801069c5: 53 push %ebx + + if (newsz >= oldsz) { + return oldsz; + } + + a = PGROUNDUP(newsz); +801069c6: 8d 99 ff 0f 00 00 lea 0xfff(%ecx),%ebx +801069cc: 81 e3 00 f0 ff ff and $0xfffff000,%ebx +int deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) { +801069d2: 83 ec 1c sub $0x1c,%esp +801069d5: 89 4d e0 mov %ecx,-0x20(%ebp) + for (; a < oldsz; a += PGSIZE) { +801069d8: 39 d3 cmp %edx,%ebx +801069da: 73 49 jae 80106a25 +801069dc: 89 c7 mov %eax,%edi +801069de: eb 0c jmp 801069ec + pte = walkpgdir(pgdir, (char*)a, 0); + if (!pte) { + a = PGADDR(PDX(a) + 1, 0, 0) - PGSIZE; +801069e0: 83 c0 01 add $0x1,%eax +801069e3: c1 e0 16 shl $0x16,%eax +801069e6: 89 c3 mov %eax,%ebx + for (; a < oldsz; a += PGSIZE) { +801069e8: 39 da cmp %ebx,%edx +801069ea: 76 39 jbe 80106a25 + pde = &pgdir[PDX(va)]; +801069ec: 89 d8 mov %ebx,%eax +801069ee: c1 e8 16 shr $0x16,%eax + if (*pde & PTE_P) { +801069f1: 8b 0c 87 mov (%edi,%eax,4),%ecx +801069f4: f6 c1 01 test $0x1,%cl +801069f7: 74 e7 je 801069e0 + return &pgtab[PTX(va)]; +801069f9: 89 de mov %ebx,%esi + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); +801069fb: 81 e1 00 f0 ff ff and $0xfffff000,%ecx + return &pgtab[PTX(va)]; +80106a01: c1 ee 0a shr $0xa,%esi +80106a04: 81 e6 fc 0f 00 00 and $0xffc,%esi +80106a0a: 8d b4 31 00 00 00 80 lea -0x80000000(%ecx,%esi,1),%esi + if (!pte) { +80106a11: 85 f6 test %esi,%esi +80106a13: 74 cb je 801069e0 + } + else if ((*pte & PTE_P) != 0) { +80106a15: 8b 06 mov (%esi),%eax +80106a17: a8 01 test $0x1,%al +80106a19: 75 15 jne 80106a30 + for (; a < oldsz; a += PGSIZE) { +80106a1b: 81 c3 00 10 00 00 add $0x1000,%ebx +80106a21: 39 da cmp %ebx,%edx +80106a23: 77 c7 ja 801069ec + kfree(v); + *pte = 0; + } + } + return newsz; +} +80106a25: 8b 45 e0 mov -0x20(%ebp),%eax +80106a28: 8d 65 f4 lea -0xc(%ebp),%esp +80106a2b: 5b pop %ebx +80106a2c: 5e pop %esi +80106a2d: 5f pop %edi +80106a2e: 5d pop %ebp +80106a2f: c3 ret + if (pa == 0) { +80106a30: 25 00 f0 ff ff and $0xfffff000,%eax +80106a35: 74 25 je 80106a5c + kfree(v); +80106a37: 83 ec 0c sub $0xc,%esp + char *v = P2V(pa); +80106a3a: 05 00 00 00 80 add $0x80000000,%eax +80106a3f: 89 55 e4 mov %edx,-0x1c(%ebp) + for (; a < oldsz; a += PGSIZE) { +80106a42: 81 c3 00 10 00 00 add $0x1000,%ebx + kfree(v); +80106a48: 50 push %eax +80106a49: e8 92 bb ff ff call 801025e0 + *pte = 0; +80106a4e: c7 06 00 00 00 00 movl $0x0,(%esi) + for (; a < oldsz; a += PGSIZE) { +80106a54: 8b 55 e4 mov -0x1c(%ebp),%edx +80106a57: 83 c4 10 add $0x10,%esp +80106a5a: eb 8c jmp 801069e8 + panic("kfree"); +80106a5c: 83 ec 0c sub $0xc,%esp +80106a5f: 68 46 76 10 80 push $0x80107646 +80106a64: e8 27 99 ff ff call 80100390 +80106a69: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80106a70 : +static int mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm) { +80106a70: 55 push %ebp +80106a71: 89 e5 mov %esp,%ebp +80106a73: 57 push %edi +80106a74: 56 push %esi +80106a75: 53 push %ebx + a = (char*)PGROUNDDOWN((uint)va); +80106a76: 89 d3 mov %edx,%ebx +80106a78: 81 e3 00 f0 ff ff and $0xfffff000,%ebx +static int mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm) { +80106a7e: 83 ec 1c sub $0x1c,%esp +80106a81: 89 45 e4 mov %eax,-0x1c(%ebp) + last = (char*)PGROUNDDOWN(((uint)va) + size - 1); +80106a84: 8d 44 0a ff lea -0x1(%edx,%ecx,1),%eax +80106a88: 25 00 f0 ff ff and $0xfffff000,%eax +80106a8d: 89 45 dc mov %eax,-0x24(%ebp) +80106a90: 8b 45 08 mov 0x8(%ebp),%eax +80106a93: 29 d8 sub %ebx,%eax +80106a95: 89 45 e0 mov %eax,-0x20(%ebp) +80106a98: eb 3d jmp 80106ad7 +80106a9a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + return &pgtab[PTX(va)]; +80106aa0: 89 da mov %ebx,%edx + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); +80106aa2: 25 00 f0 ff ff and $0xfffff000,%eax + return &pgtab[PTX(va)]; +80106aa7: c1 ea 0a shr $0xa,%edx +80106aaa: 81 e2 fc 0f 00 00 and $0xffc,%edx +80106ab0: 8d 84 10 00 00 00 80 lea -0x80000000(%eax,%edx,1),%eax + if ((pte = walkpgdir(pgdir, a, 1)) == 0) { +80106ab7: 85 c0 test %eax,%eax +80106ab9: 74 75 je 80106b30 + if (*pte & PTE_P) { +80106abb: f6 00 01 testb $0x1,(%eax) +80106abe: 0f 85 86 00 00 00 jne 80106b4a + *pte = pa | perm | PTE_P; +80106ac4: 0b 75 0c or 0xc(%ebp),%esi +80106ac7: 83 ce 01 or $0x1,%esi +80106aca: 89 30 mov %esi,(%eax) + if (a == last) { +80106acc: 3b 5d dc cmp -0x24(%ebp),%ebx +80106acf: 74 6f je 80106b40 + a += PGSIZE; +80106ad1: 81 c3 00 10 00 00 add $0x1000,%ebx + for (;;) { +80106ad7: 8b 45 e0 mov -0x20(%ebp),%eax + pde = &pgdir[PDX(va)]; +80106ada: 8b 4d e4 mov -0x1c(%ebp),%ecx +80106add: 8d 34 18 lea (%eax,%ebx,1),%esi +80106ae0: 89 d8 mov %ebx,%eax +80106ae2: c1 e8 16 shr $0x16,%eax +80106ae5: 8d 3c 81 lea (%ecx,%eax,4),%edi + if (*pde & PTE_P) { +80106ae8: 8b 07 mov (%edi),%eax +80106aea: a8 01 test $0x1,%al +80106aec: 75 b2 jne 80106aa0 + if (!alloc || (pgtab = (pte_t*)kalloc()) == 0) { +80106aee: e8 ad bc ff ff call 801027a0 +80106af3: 85 c0 test %eax,%eax +80106af5: 74 39 je 80106b30 + memset(pgtab, 0, PGSIZE); +80106af7: 83 ec 04 sub $0x4,%esp +80106afa: 89 45 d8 mov %eax,-0x28(%ebp) +80106afd: 68 00 10 00 00 push $0x1000 +80106b02: 6a 00 push $0x0 +80106b04: 50 push %eax +80106b05: e8 b6 dc ff ff call 801047c0 + *pde = V2P(pgtab) | PTE_P | PTE_W | PTE_U; +80106b0a: 8b 55 d8 mov -0x28(%ebp),%edx + return &pgtab[PTX(va)]; +80106b0d: 83 c4 10 add $0x10,%esp + *pde = V2P(pgtab) | PTE_P | PTE_W | PTE_U; +80106b10: 8d 82 00 00 00 80 lea -0x80000000(%edx),%eax +80106b16: 83 c8 07 or $0x7,%eax +80106b19: 89 07 mov %eax,(%edi) + return &pgtab[PTX(va)]; +80106b1b: 89 d8 mov %ebx,%eax +80106b1d: c1 e8 0a shr $0xa,%eax +80106b20: 25 fc 0f 00 00 and $0xffc,%eax +80106b25: 01 d0 add %edx,%eax +80106b27: eb 92 jmp 80106abb +80106b29: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +} +80106b30: 8d 65 f4 lea -0xc(%ebp),%esp + return -1; +80106b33: b8 ff ff ff ff mov $0xffffffff,%eax +} +80106b38: 5b pop %ebx +80106b39: 5e pop %esi +80106b3a: 5f pop %edi +80106b3b: 5d pop %ebp +80106b3c: c3 ret +80106b3d: 8d 76 00 lea 0x0(%esi),%esi +80106b40: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; +80106b43: 31 c0 xor %eax,%eax +} +80106b45: 5b pop %ebx +80106b46: 5e pop %esi +80106b47: 5f pop %edi +80106b48: 5d pop %ebp +80106b49: c3 ret + panic("remap"); +80106b4a: 83 ec 0c sub $0xc,%esp +80106b4d: 68 a0 7c 10 80 push $0x80107ca0 +80106b52: e8 39 98 ff ff call 80100390 +80106b57: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80106b5e: 66 90 xchg %ax,%ax + +80106b60 : +void seginit(void) { +80106b60: 55 push %ebp +80106b61: 89 e5 mov %esp,%ebp +80106b63: 83 ec 18 sub $0x18,%esp + c = &cpus[cpuid()]; +80106b66: e8 45 cf ff ff call 80103ab0 + pd[0] = size - 1; +80106b6b: ba 2f 00 00 00 mov $0x2f,%edx +80106b70: 69 c0 b0 00 00 00 imul $0xb0,%eax,%eax +80106b76: 66 89 55 f2 mov %dx,-0xe(%ebp) + c->gdt[SEG_KCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, 0); +80106b7a: c7 80 38 18 11 80 ff movl $0xffff,-0x7feee7c8(%eax) +80106b81: ff 00 00 +80106b84: c7 80 3c 18 11 80 00 movl $0xcf9a00,-0x7feee7c4(%eax) +80106b8b: 9a cf 00 + c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); +80106b8e: c7 80 40 18 11 80 ff movl $0xffff,-0x7feee7c0(%eax) +80106b95: ff 00 00 +80106b98: c7 80 44 18 11 80 00 movl $0xcf9200,-0x7feee7bc(%eax) +80106b9f: 92 cf 00 + c->gdt[SEG_UCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, DPL_USER); +80106ba2: c7 80 48 18 11 80 ff movl $0xffff,-0x7feee7b8(%eax) +80106ba9: ff 00 00 +80106bac: c7 80 4c 18 11 80 00 movl $0xcffa00,-0x7feee7b4(%eax) +80106bb3: fa cf 00 + c->gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER); +80106bb6: c7 80 50 18 11 80 ff movl $0xffff,-0x7feee7b0(%eax) +80106bbd: ff 00 00 +80106bc0: c7 80 54 18 11 80 00 movl $0xcff200,-0x7feee7ac(%eax) +80106bc7: f2 cf 00 + lgdt(c->gdt, sizeof(c->gdt)); +80106bca: 05 30 18 11 80 add $0x80111830,%eax + pd[1] = (uint)p; +80106bcf: 66 89 45 f4 mov %ax,-0xc(%ebp) + pd[2] = (uint)p >> 16; +80106bd3: c1 e8 10 shr $0x10,%eax +80106bd6: 66 89 45 f6 mov %ax,-0xa(%ebp) + asm volatile ("lgdt (%0)" : : "r" (pd)); +80106bda: 8d 45 f2 lea -0xe(%ebp),%eax +80106bdd: 0f 01 10 lgdtl (%eax) +} +80106be0: c9 leave +80106be1: c3 ret +80106be2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80106be9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80106bf0 : + lcr3(V2P(kpgdir)); // switch to the kernel page table +80106bf0: a1 e4 44 11 80 mov 0x801144e4,%eax +80106bf5: 05 00 00 00 80 add $0x80000000,%eax + return val; +} + +static inline void lcr3(uint val) { + asm volatile ("movl %0,%%cr3" : : "r" (val)); +80106bfa: 0f 22 d8 mov %eax,%cr3 +} +80106bfd: c3 ret +80106bfe: 66 90 xchg %ax,%ax + +80106c00 : +void switchuvm(struct proc *p) { +80106c00: 55 push %ebp +80106c01: 89 e5 mov %esp,%ebp +80106c03: 57 push %edi +80106c04: 56 push %esi +80106c05: 53 push %ebx +80106c06: 83 ec 1c sub $0x1c,%esp +80106c09: 8b 75 08 mov 0x8(%ebp),%esi + if (p == 0) { +80106c0c: 85 f6 test %esi,%esi +80106c0e: 0f 84 cb 00 00 00 je 80106cdf + if (p->kstack == 0) { +80106c14: 8b 46 08 mov 0x8(%esi),%eax +80106c17: 85 c0 test %eax,%eax +80106c19: 0f 84 da 00 00 00 je 80106cf9 + if (p->pgdir == 0) { +80106c1f: 8b 46 04 mov 0x4(%esi),%eax +80106c22: 85 c0 test %eax,%eax +80106c24: 0f 84 c2 00 00 00 je 80106cec + pushcli(); +80106c2a: e8 81 d9 ff ff call 801045b0 + mycpu()->gdt[SEG_TSS] = SEG16(STS_T32A, &mycpu()->ts, +80106c2f: e8 1c ce ff ff call 80103a50 +80106c34: 89 c3 mov %eax,%ebx +80106c36: e8 15 ce ff ff call 80103a50 +80106c3b: 89 c7 mov %eax,%edi +80106c3d: e8 0e ce ff ff call 80103a50 +80106c42: 83 c7 08 add $0x8,%edi +80106c45: 89 45 e4 mov %eax,-0x1c(%ebp) +80106c48: e8 03 ce ff ff call 80103a50 +80106c4d: 8b 4d e4 mov -0x1c(%ebp),%ecx +80106c50: ba 67 00 00 00 mov $0x67,%edx +80106c55: 66 89 bb 9a 00 00 00 mov %di,0x9a(%ebx) +80106c5c: 83 c0 08 add $0x8,%eax +80106c5f: 66 89 93 98 00 00 00 mov %dx,0x98(%ebx) + mycpu()->ts.iomb = (ushort) 0xFFFF; +80106c66: bf ff ff ff ff mov $0xffffffff,%edi + mycpu()->gdt[SEG_TSS] = SEG16(STS_T32A, &mycpu()->ts, +80106c6b: 83 c1 08 add $0x8,%ecx +80106c6e: c1 e8 18 shr $0x18,%eax +80106c71: c1 e9 10 shr $0x10,%ecx +80106c74: 88 83 9f 00 00 00 mov %al,0x9f(%ebx) +80106c7a: 88 8b 9c 00 00 00 mov %cl,0x9c(%ebx) +80106c80: b9 99 40 00 00 mov $0x4099,%ecx +80106c85: 66 89 8b 9d 00 00 00 mov %cx,0x9d(%ebx) + mycpu()->ts.ss0 = SEG_KDATA << 3; +80106c8c: bb 10 00 00 00 mov $0x10,%ebx + mycpu()->gdt[SEG_TSS].s = 0; +80106c91: e8 ba cd ff ff call 80103a50 +80106c96: 80 a0 9d 00 00 00 ef andb $0xef,0x9d(%eax) + mycpu()->ts.ss0 = SEG_KDATA << 3; +80106c9d: e8 ae cd ff ff call 80103a50 +80106ca2: 66 89 58 10 mov %bx,0x10(%eax) + mycpu()->ts.esp0 = (uint)p->kstack + KSTACKSIZE; +80106ca6: 8b 5e 08 mov 0x8(%esi),%ebx +80106ca9: 81 c3 00 10 00 00 add $0x1000,%ebx +80106caf: e8 9c cd ff ff call 80103a50 +80106cb4: 89 58 0c mov %ebx,0xc(%eax) + mycpu()->ts.iomb = (ushort) 0xFFFF; +80106cb7: e8 94 cd ff ff call 80103a50 +80106cbc: 66 89 78 6e mov %di,0x6e(%eax) + asm volatile ("ltr %0" : : "r" (sel)); +80106cc0: b8 28 00 00 00 mov $0x28,%eax +80106cc5: 0f 00 d8 ltr %ax + lcr3(V2P(p->pgdir)); // switch to process's address space +80106cc8: 8b 46 04 mov 0x4(%esi),%eax +80106ccb: 05 00 00 00 80 add $0x80000000,%eax + asm volatile ("movl %0,%%cr3" : : "r" (val)); +80106cd0: 0f 22 d8 mov %eax,%cr3 +} +80106cd3: 8d 65 f4 lea -0xc(%ebp),%esp +80106cd6: 5b pop %ebx +80106cd7: 5e pop %esi +80106cd8: 5f pop %edi +80106cd9: 5d pop %ebp + popcli(); +80106cda: e9 21 d9 ff ff jmp 80104600 + panic("switchuvm: no process"); +80106cdf: 83 ec 0c sub $0xc,%esp +80106ce2: 68 a6 7c 10 80 push $0x80107ca6 +80106ce7: e8 a4 96 ff ff call 80100390 + panic("switchuvm: no pgdir"); +80106cec: 83 ec 0c sub $0xc,%esp +80106cef: 68 d1 7c 10 80 push $0x80107cd1 +80106cf4: e8 97 96 ff ff call 80100390 + panic("switchuvm: no kstack"); +80106cf9: 83 ec 0c sub $0xc,%esp +80106cfc: 68 bc 7c 10 80 push $0x80107cbc +80106d01: e8 8a 96 ff ff call 80100390 +80106d06: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80106d0d: 8d 76 00 lea 0x0(%esi),%esi + +80106d10 : +void inituvm(pde_t *pgdir, char *init, uint sz) { +80106d10: 55 push %ebp +80106d11: 89 e5 mov %esp,%ebp +80106d13: 57 push %edi +80106d14: 56 push %esi +80106d15: 53 push %ebx +80106d16: 83 ec 1c sub $0x1c,%esp +80106d19: 8b 45 0c mov 0xc(%ebp),%eax +80106d1c: 8b 75 10 mov 0x10(%ebp),%esi +80106d1f: 8b 7d 08 mov 0x8(%ebp),%edi +80106d22: 89 45 e4 mov %eax,-0x1c(%ebp) + if (sz >= PGSIZE) { +80106d25: 81 fe ff 0f 00 00 cmp $0xfff,%esi +80106d2b: 77 4b ja 80106d78 + mem = kalloc(); +80106d2d: e8 6e ba ff ff call 801027a0 + memset(mem, 0, PGSIZE); +80106d32: 83 ec 04 sub $0x4,%esp +80106d35: 68 00 10 00 00 push $0x1000 + mem = kalloc(); +80106d3a: 89 c3 mov %eax,%ebx + memset(mem, 0, PGSIZE); +80106d3c: 6a 00 push $0x0 +80106d3e: 50 push %eax +80106d3f: e8 7c da ff ff call 801047c0 + mappages(pgdir, 0, PGSIZE, V2P(mem), PTE_W | PTE_U); +80106d44: 58 pop %eax +80106d45: 8d 83 00 00 00 80 lea -0x80000000(%ebx),%eax +80106d4b: 5a pop %edx +80106d4c: 6a 06 push $0x6 +80106d4e: b9 00 10 00 00 mov $0x1000,%ecx +80106d53: 31 d2 xor %edx,%edx +80106d55: 50 push %eax +80106d56: 89 f8 mov %edi,%eax +80106d58: e8 13 fd ff ff call 80106a70 + memmove(mem, init, sz); +80106d5d: 8b 45 e4 mov -0x1c(%ebp),%eax +80106d60: 89 75 10 mov %esi,0x10(%ebp) +80106d63: 83 c4 10 add $0x10,%esp +80106d66: 89 5d 08 mov %ebx,0x8(%ebp) +80106d69: 89 45 0c mov %eax,0xc(%ebp) +} +80106d6c: 8d 65 f4 lea -0xc(%ebp),%esp +80106d6f: 5b pop %ebx +80106d70: 5e pop %esi +80106d71: 5f pop %edi +80106d72: 5d pop %ebp + memmove(mem, init, sz); +80106d73: e9 e8 da ff ff jmp 80104860 + panic("inituvm: more than a page"); +80106d78: 83 ec 0c sub $0xc,%esp +80106d7b: 68 e5 7c 10 80 push $0x80107ce5 +80106d80: e8 0b 96 ff ff call 80100390 +80106d85: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80106d8c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +80106d90 : +int loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz) { +80106d90: 55 push %ebp +80106d91: 89 e5 mov %esp,%ebp +80106d93: 57 push %edi +80106d94: 56 push %esi +80106d95: 53 push %ebx +80106d96: 83 ec 1c sub $0x1c,%esp +80106d99: 8b 45 0c mov 0xc(%ebp),%eax +80106d9c: 8b 75 18 mov 0x18(%ebp),%esi + if ((uint) addr % PGSIZE != 0) { +80106d9f: a9 ff 0f 00 00 test $0xfff,%eax +80106da4: 0f 85 bb 00 00 00 jne 80106e65 + for (i = 0; i < sz; i += PGSIZE) { +80106daa: 01 f0 add %esi,%eax +80106dac: 89 f3 mov %esi,%ebx +80106dae: 89 45 e4 mov %eax,-0x1c(%ebp) + if (readi(ip, P2V(pa), offset + i, n) != n) { +80106db1: 8b 45 14 mov 0x14(%ebp),%eax +80106db4: 01 f0 add %esi,%eax +80106db6: 89 45 e0 mov %eax,-0x20(%ebp) + for (i = 0; i < sz; i += PGSIZE) { +80106db9: 85 f6 test %esi,%esi +80106dbb: 0f 84 87 00 00 00 je 80106e48 +80106dc1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + pde = &pgdir[PDX(va)]; +80106dc8: 8b 45 e4 mov -0x1c(%ebp),%eax + if (*pde & PTE_P) { +80106dcb: 8b 4d 08 mov 0x8(%ebp),%ecx +80106dce: 29 d8 sub %ebx,%eax + pde = &pgdir[PDX(va)]; +80106dd0: 89 c2 mov %eax,%edx +80106dd2: c1 ea 16 shr $0x16,%edx + if (*pde & PTE_P) { +80106dd5: 8b 14 91 mov (%ecx,%edx,4),%edx +80106dd8: f6 c2 01 test $0x1,%dl +80106ddb: 75 13 jne 80106df0 + panic("loaduvm: address should exist"); +80106ddd: 83 ec 0c sub $0xc,%esp +80106de0: 68 ff 7c 10 80 push $0x80107cff +80106de5: e8 a6 95 ff ff call 80100390 +80106dea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + return &pgtab[PTX(va)]; +80106df0: c1 e8 0a shr $0xa,%eax + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); +80106df3: 81 e2 00 f0 ff ff and $0xfffff000,%edx + return &pgtab[PTX(va)]; +80106df9: 25 fc 0f 00 00 and $0xffc,%eax +80106dfe: 8d 84 02 00 00 00 80 lea -0x80000000(%edx,%eax,1),%eax + if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) { +80106e05: 85 c0 test %eax,%eax +80106e07: 74 d4 je 80106ddd + pa = PTE_ADDR(*pte); +80106e09: 8b 00 mov (%eax),%eax + if (readi(ip, P2V(pa), offset + i, n) != n) { +80106e0b: 8b 4d e0 mov -0x20(%ebp),%ecx + if (sz - i < PGSIZE) { +80106e0e: bf 00 10 00 00 mov $0x1000,%edi + pa = PTE_ADDR(*pte); +80106e13: 25 00 f0 ff ff and $0xfffff000,%eax + if (sz - i < PGSIZE) { +80106e18: 81 fb ff 0f 00 00 cmp $0xfff,%ebx +80106e1e: 0f 46 fb cmovbe %ebx,%edi + if (readi(ip, P2V(pa), offset + i, n) != n) { +80106e21: 29 d9 sub %ebx,%ecx +80106e23: 05 00 00 00 80 add $0x80000000,%eax +80106e28: 57 push %edi +80106e29: 51 push %ecx +80106e2a: 50 push %eax +80106e2b: ff 75 10 push 0x10(%ebp) +80106e2e: e8 7d ad ff ff call 80101bb0 +80106e33: 83 c4 10 add $0x10,%esp +80106e36: 39 f8 cmp %edi,%eax +80106e38: 75 1e jne 80106e58 + for (i = 0; i < sz; i += PGSIZE) { +80106e3a: 81 eb 00 10 00 00 sub $0x1000,%ebx +80106e40: 89 f0 mov %esi,%eax +80106e42: 29 d8 sub %ebx,%eax +80106e44: 39 c6 cmp %eax,%esi +80106e46: 77 80 ja 80106dc8 +} +80106e48: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; +80106e4b: 31 c0 xor %eax,%eax +} +80106e4d: 5b pop %ebx +80106e4e: 5e pop %esi +80106e4f: 5f pop %edi +80106e50: 5d pop %ebp +80106e51: c3 ret +80106e52: 8d b6 00 00 00 00 lea 0x0(%esi),%esi +80106e58: 8d 65 f4 lea -0xc(%ebp),%esp + return -1; +80106e5b: b8 ff ff ff ff mov $0xffffffff,%eax +} +80106e60: 5b pop %ebx +80106e61: 5e pop %esi +80106e62: 5f pop %edi +80106e63: 5d pop %ebp +80106e64: c3 ret + panic("loaduvm: addr must be page aligned"); +80106e65: 83 ec 0c sub $0xc,%esp +80106e68: 68 a0 7d 10 80 push $0x80107da0 +80106e6d: e8 1e 95 ff ff call 80100390 +80106e72: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80106e79: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +80106e80 : +int allocuvm(pde_t *pgdir, uint oldsz, uint newsz) { +80106e80: 55 push %ebp +80106e81: 89 e5 mov %esp,%ebp +80106e83: 57 push %edi +80106e84: 56 push %esi +80106e85: 53 push %ebx +80106e86: 83 ec 1c sub $0x1c,%esp + if (newsz >= KERNBASE) { +80106e89: 8b 45 10 mov 0x10(%ebp),%eax +int allocuvm(pde_t *pgdir, uint oldsz, uint newsz) { +80106e8c: 8b 7d 08 mov 0x8(%ebp),%edi + if (newsz >= KERNBASE) { +80106e8f: 89 45 e4 mov %eax,-0x1c(%ebp) +80106e92: 85 c0 test %eax,%eax +80106e94: 0f 88 b6 00 00 00 js 80106f50 + if (newsz < oldsz) { +80106e9a: 3b 45 0c cmp 0xc(%ebp),%eax + return oldsz; +80106e9d: 8b 45 0c mov 0xc(%ebp),%eax + if (newsz < oldsz) { +80106ea0: 0f 82 9a 00 00 00 jb 80106f40 + a = PGROUNDUP(oldsz); +80106ea6: 8d b0 ff 0f 00 00 lea 0xfff(%eax),%esi +80106eac: 81 e6 00 f0 ff ff and $0xfffff000,%esi + for (; a < newsz; a += PGSIZE) { +80106eb2: 39 75 10 cmp %esi,0x10(%ebp) +80106eb5: 77 44 ja 80106efb +80106eb7: e9 87 00 00 00 jmp 80106f43 +80106ebc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + memset(mem, 0, PGSIZE); +80106ec0: 83 ec 04 sub $0x4,%esp +80106ec3: 68 00 10 00 00 push $0x1000 +80106ec8: 6a 00 push $0x0 +80106eca: 50 push %eax +80106ecb: e8 f0 d8 ff ff call 801047c0 + if (mappages(pgdir, (char*)a, PGSIZE, V2P(mem), PTE_W | PTE_U) < 0) { +80106ed0: 58 pop %eax +80106ed1: 8d 83 00 00 00 80 lea -0x80000000(%ebx),%eax +80106ed7: 5a pop %edx +80106ed8: 6a 06 push $0x6 +80106eda: b9 00 10 00 00 mov $0x1000,%ecx +80106edf: 89 f2 mov %esi,%edx +80106ee1: 50 push %eax +80106ee2: 89 f8 mov %edi,%eax +80106ee4: e8 87 fb ff ff call 80106a70 +80106ee9: 83 c4 10 add $0x10,%esp +80106eec: 85 c0 test %eax,%eax +80106eee: 78 78 js 80106f68 + for (; a < newsz; a += PGSIZE) { +80106ef0: 81 c6 00 10 00 00 add $0x1000,%esi +80106ef6: 39 75 10 cmp %esi,0x10(%ebp) +80106ef9: 76 48 jbe 80106f43 + mem = kalloc(); +80106efb: e8 a0 b8 ff ff call 801027a0 +80106f00: 89 c3 mov %eax,%ebx + if (mem == 0) { +80106f02: 85 c0 test %eax,%eax +80106f04: 75 ba jne 80106ec0 + cprintf("allocuvm out of memory\n"); +80106f06: 83 ec 0c sub $0xc,%esp +80106f09: 68 1d 7d 10 80 push $0x80107d1d +80106f0e: e8 9d 97 ff ff call 801006b0 + if (newsz >= oldsz) { +80106f13: 8b 45 0c mov 0xc(%ebp),%eax +80106f16: 83 c4 10 add $0x10,%esp +80106f19: 39 45 10 cmp %eax,0x10(%ebp) +80106f1c: 74 32 je 80106f50 +80106f1e: 8b 55 10 mov 0x10(%ebp),%edx +80106f21: 89 c1 mov %eax,%ecx +80106f23: 89 f8 mov %edi,%eax +80106f25: e8 96 fa ff ff call 801069c0 + return 0; +80106f2a: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +} +80106f31: 8b 45 e4 mov -0x1c(%ebp),%eax +80106f34: 8d 65 f4 lea -0xc(%ebp),%esp +80106f37: 5b pop %ebx +80106f38: 5e pop %esi +80106f39: 5f pop %edi +80106f3a: 5d pop %ebp +80106f3b: c3 ret +80106f3c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + return oldsz; +80106f40: 89 45 e4 mov %eax,-0x1c(%ebp) +} +80106f43: 8b 45 e4 mov -0x1c(%ebp),%eax +80106f46: 8d 65 f4 lea -0xc(%ebp),%esp +80106f49: 5b pop %ebx +80106f4a: 5e pop %esi +80106f4b: 5f pop %edi +80106f4c: 5d pop %ebp +80106f4d: c3 ret +80106f4e: 66 90 xchg %ax,%ax + return 0; +80106f50: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +} +80106f57: 8b 45 e4 mov -0x1c(%ebp),%eax +80106f5a: 8d 65 f4 lea -0xc(%ebp),%esp +80106f5d: 5b pop %ebx +80106f5e: 5e pop %esi +80106f5f: 5f pop %edi +80106f60: 5d pop %ebp +80106f61: c3 ret +80106f62: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + cprintf("allocuvm out of memory (2)\n"); +80106f68: 83 ec 0c sub $0xc,%esp +80106f6b: 68 35 7d 10 80 push $0x80107d35 +80106f70: e8 3b 97 ff ff call 801006b0 + if (newsz >= oldsz) { +80106f75: 8b 45 0c mov 0xc(%ebp),%eax +80106f78: 83 c4 10 add $0x10,%esp +80106f7b: 39 45 10 cmp %eax,0x10(%ebp) +80106f7e: 74 0c je 80106f8c +80106f80: 8b 55 10 mov 0x10(%ebp),%edx +80106f83: 89 c1 mov %eax,%ecx +80106f85: 89 f8 mov %edi,%eax +80106f87: e8 34 fa ff ff call 801069c0 + kfree(mem); +80106f8c: 83 ec 0c sub $0xc,%esp +80106f8f: 53 push %ebx +80106f90: e8 4b b6 ff ff call 801025e0 + return 0; +80106f95: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +80106f9c: 83 c4 10 add $0x10,%esp +} +80106f9f: 8b 45 e4 mov -0x1c(%ebp),%eax +80106fa2: 8d 65 f4 lea -0xc(%ebp),%esp +80106fa5: 5b pop %ebx +80106fa6: 5e pop %esi +80106fa7: 5f pop %edi +80106fa8: 5d pop %ebp +80106fa9: c3 ret +80106faa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80106fb0 : +int deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) { +80106fb0: 55 push %ebp +80106fb1: 89 e5 mov %esp,%ebp +80106fb3: 8b 55 0c mov 0xc(%ebp),%edx +80106fb6: 8b 4d 10 mov 0x10(%ebp),%ecx +80106fb9: 8b 45 08 mov 0x8(%ebp),%eax + if (newsz >= oldsz) { +80106fbc: 39 d1 cmp %edx,%ecx +80106fbe: 73 10 jae 80106fd0 +} +80106fc0: 5d pop %ebp +80106fc1: e9 fa f9 ff ff jmp 801069c0 +80106fc6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80106fcd: 8d 76 00 lea 0x0(%esi),%esi +80106fd0: 89 d0 mov %edx,%eax +80106fd2: 5d pop %ebp +80106fd3: c3 ret +80106fd4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +80106fdb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +80106fdf: 90 nop + +80106fe0 : + +// Free a page table and all the physical memory pages +// in the user part. +void freevm(pde_t *pgdir) { +80106fe0: 55 push %ebp +80106fe1: 89 e5 mov %esp,%ebp +80106fe3: 57 push %edi +80106fe4: 56 push %esi +80106fe5: 53 push %ebx +80106fe6: 83 ec 0c sub $0xc,%esp +80106fe9: 8b 75 08 mov 0x8(%ebp),%esi + uint i; + + if (pgdir == 0) { +80106fec: 85 f6 test %esi,%esi +80106fee: 74 59 je 80107049 + if (newsz >= oldsz) { +80106ff0: 31 c9 xor %ecx,%ecx +80106ff2: ba 00 00 00 80 mov $0x80000000,%edx +80106ff7: 89 f0 mov %esi,%eax +80106ff9: 89 f3 mov %esi,%ebx +80106ffb: e8 c0 f9 ff ff call 801069c0 + panic("freevm: no pgdir"); + } + deallocuvm(pgdir, KERNBASE, 0); + for (i = 0; i < NPDENTRIES; i++) { +80107000: 8d be 00 10 00 00 lea 0x1000(%esi),%edi +80107006: eb 0f jmp 80107017 +80107008: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010700f: 90 nop +80107010: 83 c3 04 add $0x4,%ebx +80107013: 39 df cmp %ebx,%edi +80107015: 74 23 je 8010703a + if (pgdir[i] & PTE_P) { +80107017: 8b 03 mov (%ebx),%eax +80107019: a8 01 test $0x1,%al +8010701b: 74 f3 je 80107010 + char * v = P2V(PTE_ADDR(pgdir[i])); +8010701d: 25 00 f0 ff ff and $0xfffff000,%eax + kfree(v); +80107022: 83 ec 0c sub $0xc,%esp + for (i = 0; i < NPDENTRIES; i++) { +80107025: 83 c3 04 add $0x4,%ebx + char * v = P2V(PTE_ADDR(pgdir[i])); +80107028: 05 00 00 00 80 add $0x80000000,%eax + kfree(v); +8010702d: 50 push %eax +8010702e: e8 ad b5 ff ff call 801025e0 +80107033: 83 c4 10 add $0x10,%esp + for (i = 0; i < NPDENTRIES; i++) { +80107036: 39 df cmp %ebx,%edi +80107038: 75 dd jne 80107017 + } + } + kfree((char*)pgdir); +8010703a: 89 75 08 mov %esi,0x8(%ebp) +} +8010703d: 8d 65 f4 lea -0xc(%ebp),%esp +80107040: 5b pop %ebx +80107041: 5e pop %esi +80107042: 5f pop %edi +80107043: 5d pop %ebp + kfree((char*)pgdir); +80107044: e9 97 b5 ff ff jmp 801025e0 + panic("freevm: no pgdir"); +80107049: 83 ec 0c sub $0xc,%esp +8010704c: 68 51 7d 10 80 push $0x80107d51 +80107051: e8 3a 93 ff ff call 80100390 +80107056: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010705d: 8d 76 00 lea 0x0(%esi),%esi + +80107060 : +pde_t*setupkvm(void) { +80107060: 55 push %ebp +80107061: 89 e5 mov %esp,%ebp +80107063: 56 push %esi +80107064: 53 push %ebx + if ((pgdir = (pde_t*)kalloc()) == 0) { +80107065: e8 36 b7 ff ff call 801027a0 +8010706a: 89 c6 mov %eax,%esi +8010706c: 85 c0 test %eax,%eax +8010706e: 74 42 je 801070b2 + memset(pgdir, 0, PGSIZE); +80107070: 83 ec 04 sub $0x4,%esp + for (k = kmap; k < &kmap[NELEM(kmap)]; k++) { +80107073: bb 20 a4 10 80 mov $0x8010a420,%ebx + memset(pgdir, 0, PGSIZE); +80107078: 68 00 10 00 00 push $0x1000 +8010707d: 6a 00 push $0x0 +8010707f: 50 push %eax +80107080: e8 3b d7 ff ff call 801047c0 +80107085: 83 c4 10 add $0x10,%esp + (uint)k->phys_start, k->perm) < 0) { +80107088: 8b 43 04 mov 0x4(%ebx),%eax + if (mappages(pgdir, k->virt, k->phys_end - k->phys_start, +8010708b: 83 ec 08 sub $0x8,%esp +8010708e: 8b 4b 08 mov 0x8(%ebx),%ecx +80107091: ff 73 0c push 0xc(%ebx) +80107094: 8b 13 mov (%ebx),%edx +80107096: 50 push %eax +80107097: 29 c1 sub %eax,%ecx +80107099: 89 f0 mov %esi,%eax +8010709b: e8 d0 f9 ff ff call 80106a70 +801070a0: 83 c4 10 add $0x10,%esp +801070a3: 85 c0 test %eax,%eax +801070a5: 78 19 js 801070c0 + for (k = kmap; k < &kmap[NELEM(kmap)]; k++) { +801070a7: 83 c3 10 add $0x10,%ebx +801070aa: 81 fb 60 a4 10 80 cmp $0x8010a460,%ebx +801070b0: 75 d6 jne 80107088 +} +801070b2: 8d 65 f8 lea -0x8(%ebp),%esp +801070b5: 89 f0 mov %esi,%eax +801070b7: 5b pop %ebx +801070b8: 5e pop %esi +801070b9: 5d pop %ebp +801070ba: c3 ret +801070bb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801070bf: 90 nop + freevm(pgdir); +801070c0: 83 ec 0c sub $0xc,%esp +801070c3: 56 push %esi + return 0; +801070c4: 31 f6 xor %esi,%esi + freevm(pgdir); +801070c6: e8 15 ff ff ff call 80106fe0 + return 0; +801070cb: 83 c4 10 add $0x10,%esp +} +801070ce: 8d 65 f8 lea -0x8(%ebp),%esp +801070d1: 89 f0 mov %esi,%eax +801070d3: 5b pop %ebx +801070d4: 5e pop %esi +801070d5: 5d pop %ebp +801070d6: c3 ret +801070d7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801070de: 66 90 xchg %ax,%ax + +801070e0 : +void kvmalloc(void) { +801070e0: 55 push %ebp +801070e1: 89 e5 mov %esp,%ebp +801070e3: 83 ec 08 sub $0x8,%esp + kpgdir = setupkvm(); +801070e6: e8 75 ff ff ff call 80107060 +801070eb: a3 e4 44 11 80 mov %eax,0x801144e4 + lcr3(V2P(kpgdir)); // switch to the kernel page table +801070f0: 05 00 00 00 80 add $0x80000000,%eax +801070f5: 0f 22 d8 mov %eax,%cr3 +} +801070f8: c9 leave +801070f9: c3 ret +801070fa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +80107100 : + +// Clear PTE_U on a page. Used to create an inaccessible +// page beneath the user stack. +void clearpteu(pde_t *pgdir, char *uva) { +80107100: 55 push %ebp +80107101: 89 e5 mov %esp,%ebp +80107103: 83 ec 08 sub $0x8,%esp +80107106: 8b 45 0c mov 0xc(%ebp),%eax + if (*pde & PTE_P) { +80107109: 8b 55 08 mov 0x8(%ebp),%edx + pde = &pgdir[PDX(va)]; +8010710c: 89 c1 mov %eax,%ecx +8010710e: c1 e9 16 shr $0x16,%ecx + if (*pde & PTE_P) { +80107111: 8b 14 8a mov (%edx,%ecx,4),%edx +80107114: f6 c2 01 test $0x1,%dl +80107117: 75 17 jne 80107130 + pte_t *pte; + + pte = walkpgdir(pgdir, uva, 0); + if (pte == 0) { + panic("clearpteu"); +80107119: 83 ec 0c sub $0xc,%esp +8010711c: 68 62 7d 10 80 push $0x80107d62 +80107121: e8 6a 92 ff ff call 80100390 +80107126: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010712d: 8d 76 00 lea 0x0(%esi),%esi + return &pgtab[PTX(va)]; +80107130: c1 e8 0a shr $0xa,%eax + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); +80107133: 81 e2 00 f0 ff ff and $0xfffff000,%edx + return &pgtab[PTX(va)]; +80107139: 25 fc 0f 00 00 and $0xffc,%eax +8010713e: 8d 84 02 00 00 00 80 lea -0x80000000(%edx,%eax,1),%eax + if (pte == 0) { +80107145: 85 c0 test %eax,%eax +80107147: 74 d0 je 80107119 + } + *pte &= ~PTE_U; +80107149: 83 20 fb andl $0xfffffffb,(%eax) +} +8010714c: c9 leave +8010714d: c3 ret +8010714e: 66 90 xchg %ax,%ax + +80107150 : + +// Given a parent process's page table, create a copy +// of it for a child. +pde_t* copyuvm(pde_t *pgdir, uint sz) { +80107150: 55 push %ebp +80107151: 89 e5 mov %esp,%ebp +80107153: 57 push %edi +80107154: 56 push %esi +80107155: 53 push %ebx +80107156: 83 ec 1c sub $0x1c,%esp + pde_t *d; + pte_t *pte; + uint pa, i, flags; + char *mem; + + if ((d = setupkvm()) == 0) { +80107159: e8 02 ff ff ff call 80107060 +8010715e: 89 45 e0 mov %eax,-0x20(%ebp) +80107161: 85 c0 test %eax,%eax +80107163: 0f 84 bd 00 00 00 je 80107226 + return 0; + } + for (i = 0; i < sz; i += PGSIZE) { +80107169: 8b 5d 0c mov 0xc(%ebp),%ebx +8010716c: 85 db test %ebx,%ebx +8010716e: 0f 84 b2 00 00 00 je 80107226 +80107174: 31 f6 xor %esi,%esi +80107176: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010717d: 8d 76 00 lea 0x0(%esi),%esi + if (*pde & PTE_P) { +80107180: 8b 4d 08 mov 0x8(%ebp),%ecx + pde = &pgdir[PDX(va)]; +80107183: 89 f0 mov %esi,%eax +80107185: c1 e8 16 shr $0x16,%eax + if (*pde & PTE_P) { +80107188: 8b 04 81 mov (%ecx,%eax,4),%eax +8010718b: a8 01 test $0x1,%al +8010718d: 75 11 jne 801071a0 + if ((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) { + panic("copyuvm: pte should exist"); +8010718f: 83 ec 0c sub $0xc,%esp +80107192: 68 6c 7d 10 80 push $0x80107d6c +80107197: e8 f4 91 ff ff call 80100390 +8010719c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + return &pgtab[PTX(va)]; +801071a0: 89 f2 mov %esi,%edx + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); +801071a2: 25 00 f0 ff ff and $0xfffff000,%eax + return &pgtab[PTX(va)]; +801071a7: c1 ea 0a shr $0xa,%edx +801071aa: 81 e2 fc 0f 00 00 and $0xffc,%edx +801071b0: 8d 84 10 00 00 00 80 lea -0x80000000(%eax,%edx,1),%eax + if ((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) { +801071b7: 85 c0 test %eax,%eax +801071b9: 74 d4 je 8010718f + } + if (!(*pte & PTE_P)) { +801071bb: 8b 00 mov (%eax),%eax +801071bd: a8 01 test $0x1,%al +801071bf: 0f 84 c2 00 00 00 je 80107287 + panic("copyuvm: page not present"); + } + pa = PTE_ADDR(*pte); +801071c5: 89 c7 mov %eax,%edi + flags = PTE_FLAGS(*pte); +801071c7: 25 ff 0f 00 00 and $0xfff,%eax +801071cc: 89 45 e4 mov %eax,-0x1c(%ebp) + pa = PTE_ADDR(*pte); +801071cf: 81 e7 00 f0 ff ff and $0xfffff000,%edi + if ((mem = kalloc()) == 0) { +801071d5: e8 c6 b5 ff ff call 801027a0 +801071da: 89 c3 mov %eax,%ebx +801071dc: 85 c0 test %eax,%eax +801071de: 74 58 je 80107238 + freevm(d); + return 0; + } + memmove(mem, (char*)P2V(pa), PGSIZE); +801071e0: 83 ec 04 sub $0x4,%esp +801071e3: 81 c7 00 00 00 80 add $0x80000000,%edi +801071e9: 68 00 10 00 00 push $0x1000 +801071ee: 57 push %edi +801071ef: 50 push %eax +801071f0: e8 6b d6 ff ff call 80104860 + if (mappages(d, (void*)i, PGSIZE, V2P(mem), flags) < 0) { +801071f5: 8d 83 00 00 00 80 lea -0x80000000(%ebx),%eax +801071fb: 5a pop %edx +801071fc: 59 pop %ecx +801071fd: ff 75 e4 push -0x1c(%ebp) +80107200: b9 00 10 00 00 mov $0x1000,%ecx +80107205: 89 f2 mov %esi,%edx +80107207: 50 push %eax +80107208: 8b 45 e0 mov -0x20(%ebp),%eax +8010720b: e8 60 f8 ff ff call 80106a70 +80107210: 83 c4 10 add $0x10,%esp +80107213: 85 c0 test %eax,%eax +80107215: 78 49 js 80107260 + for (i = 0; i < sz; i += PGSIZE) { +80107217: 81 c6 00 10 00 00 add $0x1000,%esi +8010721d: 39 75 0c cmp %esi,0xc(%ebp) +80107220: 0f 87 5a ff ff ff ja 80107180 + freevm(d); + return 0; + } + } + return d; +} +80107226: 8b 45 e0 mov -0x20(%ebp),%eax +80107229: 8d 65 f4 lea -0xc(%ebp),%esp +8010722c: 5b pop %ebx +8010722d: 5e pop %esi +8010722e: 5f pop %edi +8010722f: 5d pop %ebp +80107230: c3 ret +80107231: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + freevm(d); +80107238: 83 ec 0c sub $0xc,%esp +8010723b: ff 75 e0 push -0x20(%ebp) +8010723e: e8 9d fd ff ff call 80106fe0 + return 0; +80107243: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) +8010724a: 83 c4 10 add $0x10,%esp +} +8010724d: 8b 45 e0 mov -0x20(%ebp),%eax +80107250: 8d 65 f4 lea -0xc(%ebp),%esp +80107253: 5b pop %ebx +80107254: 5e pop %esi +80107255: 5f pop %edi +80107256: 5d pop %ebp +80107257: c3 ret +80107258: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010725f: 90 nop + kfree(mem); +80107260: 83 ec 0c sub $0xc,%esp +80107263: 53 push %ebx +80107264: e8 77 b3 ff ff call 801025e0 + freevm(d); +80107269: 58 pop %eax +8010726a: ff 75 e0 push -0x20(%ebp) +8010726d: e8 6e fd ff ff call 80106fe0 + return 0; +80107272: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) +80107279: 83 c4 10 add $0x10,%esp +} +8010727c: 8b 45 e0 mov -0x20(%ebp),%eax +8010727f: 8d 65 f4 lea -0xc(%ebp),%esp +80107282: 5b pop %ebx +80107283: 5e pop %esi +80107284: 5f pop %edi +80107285: 5d pop %ebp +80107286: c3 ret + panic("copyuvm: page not present"); +80107287: 83 ec 0c sub $0xc,%esp +8010728a: 68 86 7d 10 80 push $0x80107d86 +8010728f: e8 fc 90 ff ff call 80100390 +80107294: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +8010729b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010729f: 90 nop + +801072a0 : + + +// Map user virtual address to kernel address. +char*uva2ka(pde_t *pgdir, char *uva) { +801072a0: 55 push %ebp +801072a1: 89 e5 mov %esp,%ebp +801072a3: 8b 45 0c mov 0xc(%ebp),%eax + if (*pde & PTE_P) { +801072a6: 8b 55 08 mov 0x8(%ebp),%edx + pde = &pgdir[PDX(va)]; +801072a9: 89 c1 mov %eax,%ecx +801072ab: c1 e9 16 shr $0x16,%ecx + if (*pde & PTE_P) { +801072ae: 8b 14 8a mov (%edx,%ecx,4),%edx +801072b1: f6 c2 01 test $0x1,%dl +801072b4: 0f 84 00 01 00 00 je 801073ba + return &pgtab[PTX(va)]; +801072ba: c1 e8 0c shr $0xc,%eax + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); +801072bd: 81 e2 00 f0 ff ff and $0xfffff000,%edx + } + if ((*pte & PTE_U) == 0) { + return 0; + } + return (char*)P2V(PTE_ADDR(*pte)); +} +801072c3: 5d pop %ebp + return &pgtab[PTX(va)]; +801072c4: 25 ff 03 00 00 and $0x3ff,%eax + if ((*pte & PTE_P) == 0) { +801072c9: 8b 84 82 00 00 00 80 mov -0x80000000(%edx,%eax,4),%eax + if ((*pte & PTE_U) == 0) { +801072d0: 89 c2 mov %eax,%edx + return (char*)P2V(PTE_ADDR(*pte)); +801072d2: 25 00 f0 ff ff and $0xfffff000,%eax + if ((*pte & PTE_U) == 0) { +801072d7: 83 e2 05 and $0x5,%edx + return (char*)P2V(PTE_ADDR(*pte)); +801072da: 05 00 00 00 80 add $0x80000000,%eax +801072df: 83 fa 05 cmp $0x5,%edx +801072e2: ba 00 00 00 00 mov $0x0,%edx +801072e7: 0f 45 c2 cmovne %edx,%eax +} +801072ea: c3 ret +801072eb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +801072ef: 90 nop + +801072f0 : + +// Copy len bytes from p to user address va in page table pgdir. +// Most useful when pgdir is not the current page table. +// uva2ka ensures this only works for PTE_U pages. +int copyout(pde_t *pgdir, uint va, void *p, uint len) { +801072f0: 55 push %ebp +801072f1: 89 e5 mov %esp,%ebp +801072f3: 57 push %edi +801072f4: 56 push %esi +801072f5: 53 push %ebx +801072f6: 83 ec 0c sub $0xc,%esp +801072f9: 8b 75 14 mov 0x14(%ebp),%esi +801072fc: 8b 45 0c mov 0xc(%ebp),%eax +801072ff: 8b 55 10 mov 0x10(%ebp),%edx + char *buf, *pa0; + uint n, va0; + + buf = (char*)p; + while (len > 0) { +80107302: 85 f6 test %esi,%esi +80107304: 75 51 jne 80107357 +80107306: e9 a5 00 00 00 jmp 801073b0 +8010730b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +8010730f: 90 nop + return (char*)P2V(PTE_ADDR(*pte)); +80107310: 81 e3 00 f0 ff ff and $0xfffff000,%ebx +80107316: 8d 8b 00 00 00 80 lea -0x80000000(%ebx),%ecx + va0 = (uint)PGROUNDDOWN(va); + pa0 = uva2ka(pgdir, (char*)va0); + if (pa0 == 0) { +8010731c: 81 fb 00 00 00 80 cmp $0x80000000,%ebx +80107322: 74 75 je 80107399 + return -1; + } + n = PGSIZE - (va - va0); +80107324: 89 fb mov %edi,%ebx + if (n > len) { + n = len; + } + memmove(pa0 + (va - va0), buf, n); +80107326: 89 55 10 mov %edx,0x10(%ebp) + n = PGSIZE - (va - va0); +80107329: 29 c3 sub %eax,%ebx +8010732b: 81 c3 00 10 00 00 add $0x1000,%ebx +80107331: 39 f3 cmp %esi,%ebx +80107333: 0f 47 de cmova %esi,%ebx + memmove(pa0 + (va - va0), buf, n); +80107336: 29 f8 sub %edi,%eax +80107338: 83 ec 04 sub $0x4,%esp +8010733b: 01 c1 add %eax,%ecx +8010733d: 53 push %ebx +8010733e: 52 push %edx +8010733f: 51 push %ecx +80107340: e8 1b d5 ff ff call 80104860 + len -= n; + buf += n; +80107345: 8b 55 10 mov 0x10(%ebp),%edx + va = va0 + PGSIZE; +80107348: 8d 87 00 10 00 00 lea 0x1000(%edi),%eax + while (len > 0) { +8010734e: 83 c4 10 add $0x10,%esp + buf += n; +80107351: 01 da add %ebx,%edx + while (len > 0) { +80107353: 29 de sub %ebx,%esi +80107355: 74 59 je 801073b0 + if (*pde & PTE_P) { +80107357: 8b 5d 08 mov 0x8(%ebp),%ebx + pde = &pgdir[PDX(va)]; +8010735a: 89 c1 mov %eax,%ecx + va0 = (uint)PGROUNDDOWN(va); +8010735c: 89 c7 mov %eax,%edi + pde = &pgdir[PDX(va)]; +8010735e: c1 e9 16 shr $0x16,%ecx + va0 = (uint)PGROUNDDOWN(va); +80107361: 81 e7 00 f0 ff ff and $0xfffff000,%edi + if (*pde & PTE_P) { +80107367: 8b 0c 8b mov (%ebx,%ecx,4),%ecx +8010736a: f6 c1 01 test $0x1,%cl +8010736d: 0f 84 4e 00 00 00 je 801073c1 + return &pgtab[PTX(va)]; +80107373: 89 fb mov %edi,%ebx + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); +80107375: 81 e1 00 f0 ff ff and $0xfffff000,%ecx + return &pgtab[PTX(va)]; +8010737b: c1 eb 0c shr $0xc,%ebx +8010737e: 81 e3 ff 03 00 00 and $0x3ff,%ebx + if ((*pte & PTE_P) == 0) { +80107384: 8b 9c 99 00 00 00 80 mov -0x80000000(%ecx,%ebx,4),%ebx + if ((*pte & PTE_U) == 0) { +8010738b: 89 d9 mov %ebx,%ecx +8010738d: 83 e1 05 and $0x5,%ecx +80107390: 83 f9 05 cmp $0x5,%ecx +80107393: 0f 84 77 ff ff ff je 80107310 + } + return 0; +} +80107399: 8d 65 f4 lea -0xc(%ebp),%esp + return -1; +8010739c: b8 ff ff ff ff mov $0xffffffff,%eax +} +801073a1: 5b pop %ebx +801073a2: 5e pop %esi +801073a3: 5f pop %edi +801073a4: 5d pop %ebp +801073a5: c3 ret +801073a6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi +801073ad: 8d 76 00 lea 0x0(%esi),%esi +801073b0: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; +801073b3: 31 c0 xor %eax,%eax +} +801073b5: 5b pop %ebx +801073b6: 5e pop %esi +801073b7: 5f pop %edi +801073b8: 5d pop %ebp +801073b9: c3 ret + +801073ba : + if ((*pte & PTE_P) == 0) { +801073ba: a1 00 00 00 00 mov 0x0,%eax +801073bf: 0f 0b ud2 + +801073c1 : +801073c1: a1 00 00 00 00 mov 0x0,%eax +801073c6: 0f 0b ud2 diff --git a/kernel.ld b/kernel.ld new file mode 100644 index 0000000..4e12e14 --- /dev/null +++ b/kernel.ld @@ -0,0 +1,64 @@ +/* Simple linker script for the JOS kernel. + See the GNU ld 'info' manual ("info ld") to learn the syntax. */ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + /* Link the kernel at this address: "." means the current address */ + /* Must be equal to KERNLINK */ + . = 0x80100000; + + .text : AT(0x100000) { + *(.text .stub .text.* .gnu.linkonce.t.*) + } + + PROVIDE(etext = .); /* Define the 'etext' symbol to this value */ + + .rodata : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + } + + /* Include debugging information in kernel memory */ + .stab : { + PROVIDE(__STAB_BEGIN__ = .); + *(.stab); + PROVIDE(__STAB_END__ = .); + } + + .stabstr : { + PROVIDE(__STABSTR_BEGIN__ = .); + *(.stabstr); + PROVIDE(__STABSTR_END__ = .); + } + + /* Adjust the address for the data segment to the next page */ + . = ALIGN(0x1000); + + /* Conventionally, Unix linkers provide pseudo-symbols + * etext, edata, and end, at the end of the text, data, and bss. + * For the kernel mapping, we need the address at the beginning + * of the data section, but that's not one of the conventional + * symbols, because the convention started before there was a + * read-only rodata section between text and data. */ + PROVIDE(data = .); + + /* The data segment */ + .data : { + *(.data) + } + + PROVIDE(edata = .); + + .bss : { + *(.bss) + } + + PROVIDE(end = .); + + /DISCARD/ : { + *(.eh_frame .note.GNU-stack) + } +} diff --git a/kernel.sym b/kernel.sym new file mode 100644 index 0000000..7d07730 --- /dev/null +++ b/kernel.sym @@ -0,0 +1,511 @@ +00000000 bio.c +00000000 console.c +8010ef40 cons +8010ef78 panicked +80100410 consputc.part.0 +80100610 printint +80107450 digits.0 +00000000 exec.c +00000000 file.c +00000000 fs.c +801012e0 bfree +80101360 balloc +80101470 iget +80101570 bmap +80101eb0 namex +00000000 ide.c +80102200 idestart +80111620 idelock +80111600 havedisk1 +80111604 idequeue +00000000 ioapic.c +00000000 kalloc.c +00000000 kbd.c +8011169c shift.1 +80107780 shiftcode +80107680 togglecode +80107660 charcode.0 +80108200 normalmap +80108100 shiftmap +80108000 ctlmap +00000000 lapic.c +00000000 log.c +80102ce0 install_trans +80102d80 write_head +00000000 main.c +80103120 mpmain +80103160 mpenter +00000000 mp.c +801032b0 mpsearch1 +00000000 picirq.c +00000000 pipe.c +00000000 proc.c +80103910 allocproc +8010a000 first.1 +80113c74 initproc +80107a2c states.0 +00000000 sleeplock.c +00000000 spinlock.c +00000000 string.c +00000000 syscall.c +80107aa0 syscalls +00000000 sysfile.c +80104c30 create +00000000 sysproc.c +00000000 trap.c +00000000 uart.c +80105dc0 uartgetc +801144e0 uart +00000000 vm.c +801069c0 deallocuvm.part.0 +80106a70 mappages +8010a420 kmap +801073ba uva2ka.cold +801073c1 copyout.cold +80100280 consoleread +8010690f vector242 +80106366 vector119 +8010000c entry +80106246 vector87 +8010623d vector86 +80104980 safestrcpy +80104f50 sys_close +8010697b vector251 +8010626a vector91 +80106060 vector33 +8010654f vector162 +80104150 yield +801116c0 log +80111660 kmem +801067b3 vector213 +80106303 vector108 +80105df0 uartinit +801060ba vector43 +80102a30 lapiceoi +80106573 vector165 +80106663 vector185 +801024f0 ioapicinit +80106342 vector115 +80101140 fileread +80106381 vector122 +801058b0 sys_sbrk +801117a0 ioapicid +80106507 vector156 +80106933 vector245 +80111654 ioapic +80106693 vector189 +80105f84 vector7 +8010615c vector61 +8010600f vector24 +8010631e vector111 +80106717 vector200 +80106192 vector67 +8010642f vector138 +801061d1 vector74 +80103e30 sched +80104860 memmove +80106138 vector57 +80104bc0 syscall +801067bf vector214 +801062b2 vector99 +80103ab0 cpuid +80101cb0 writei +80106453 vector141 +80105830 sys_fork +80100b20 cleanupexec +8010a520 bcache +801065c7 vector172 +80106903 vector241 +80104550 getcallerpcs +801054c0 sys_mkdir +80106993 vector253 +80105f60 vector3 +80105f57 vector2 +80101de0 namecmp +8010685b vector227 +8010678f vector210 +80104b40 argstr +80106837 vector224 +8010eea0 inputBuffer +801060a8 vector41 +801006b0 cprintf +80100fc0 filedup +801021c0 namei +80105ff4 vector21 +80100040 binit +80106603 vector177 +8010635d vector118 +801061ad vector70 +801061a4 vector69 +801068d3 vector237 +80106177 vector64 +8010602a vector27 +801063e7 vector132 +8010666f vector186 +80104e50 sys_read +801067e3 vector217 +801049f0 fetchint +80107060 setupkvm +801048c0 memcpy +80106fe0 freevm +80105f4e vector1 +8010660f vector178 +8010608d vector38 +801025e0 kfree +801068df vector238 +801059e0 sys_greeting +80103a50 mycpu +801019d0 iput +801063f3 vector133 +801061c8 vector73 +80106477 vector144 +8010699f vector254 +80101640 readsb +8010a004 nextpid +801062c4 vector101 +8010679b vector211 +80103330 mpinit +801065df vector174 +8010691b vector243 +80100f30 fileinit +80105020 cleanupsyslink +80104530 initlock +801063b7 vector128 +801072f0 copyout +80106210 vector81 +801041a0 sleep +80102a50 microdelay +80105fb2 vector13 +80106102 vector51 +80105fc9 vector16 +8010ee80 input +801068f7 vector240 +8010611d vector54 +80105fe2 vector19 +80106273 vector92 +80106927 vector244 +80101b80 stati +80106447 vector140 +80105860 sys_kill +801060cc vector45 +801061fe vector79 +80103690 pipeclose +80106873 vector229 +8010651f vector158 +80104fb0 sys_fstat +801005a0 consolewrite +80106096 vector39 +80106597 vector168 +80102ef0 end_op +80106072 vector35 +80106330 vector113 +80102680 freerange +8010639c vector125 +80106e80 allocuvm +80105a66 trapret +801067d7 vector216 +8010616e vector63 +80106021 vector26 +801066c3 vector193 +80102910 lapicinit +801066e7 vector196 +80106783 vector209 +80105f69 vector4 +801065af vector170 +801144f0 stack +80106417 vector136 +80105f9d vector10 +8010675f vector206 +80101980 iunlock +80105900 sys_sleep +801069ab vector255 +80106633 vector181 +8010614a vector59 +80106234 vector85 +8010622b vector84 +8010664b vector183 +8010652b vector159 +801067a7 vector212 +80105060 sys_link +801060de vector47 +80106867 vector228 +801060b1 vector42 +80106339 vector114 +801072a0 uva2ka +801065eb vector175 +8010646b vector143 +80100f50 filealloc +80104260 wakeup +801063cf vector130 +8010693f vector246 +80105f94 vector9 +8010645f vector142 +801062bb vector100 +80106723 vector201 +80107100 clearpteu +80103ad0 myproc +80105a80 tvinit +80106153 vector60 +80106006 vector23 +80101870 idup +801068c7 vector236 +801028f0 kbdintr +80105380 sys_open +8010688b vector231 +80106189 vector66 +8010603c vector29 +80101bb0 readi +8010640b vector135 +801008e0 consoleintr +801042c0 kill +801061ec vector77 +80101730 ialloc +80106627 vector180 +801144e4 kpgdir +80106777 vector208 +80102af0 cmostime +80105f30 uartintr +801062a9 vector98 +801062a0 vector97 +801065f7 vector176 +801066cf vector194 +80106057 vector32 +801154f0 end +8010670b vector199 +80100890 consoleget +801063db vector131 +80106987 vector252 +801011d0 filewrite +80105f45 vector0 +80104a80 argint +80103550 cleanuppipealloc +80100b70 exec +80106483 vector145 +80104ed0 sys_write +801046a0 release +80104a30 fetchstr +801062fa vector107 +8010609f vector40 +80104020 wait +801062cd vector102 +80109000 entrypgdir +0010000c _start +8010612f vector56 +8010619b vector68 +80105f7b vector6 +8010a48c _binary_initcode_end +80100000 multiboot_header +801063c3 vector129 +80103d90 scheduler +80101e00 dirlookup +801066f3 vector197 +80101010 fileclose +80102e80 begin_op +801064d7 vector152 +801070e0 kvmalloc +8010687f vector230 +801048d0 strncmp +80106084 vector37 +80106753 vector205 +80106543 vector161 +80113ca0 tickslock +80103730 pipewrite +80104920 strncpy +801061b6 vector71 +80107150 copyuvm +8010ef80 ftable +80106537 vector160 +80104ad0 argptr +801067cb vector215 +80106513 vector157 +80104dd0 sys_dup +80106327 vector112 +80100390 panic +801039e0 forkret +8010663f vector182 +80105fab vector12 +80104810 memcmp +80102810 kbdgetc +8010630c vector109 +80105feb vector20 +80103c70 fork +80106114 vector53 +80105fd9 vector18 +0000007a _binary_entryother_size +801117c0 cpus +801044a0 releasesleep +8010628e vector95 +80105820 sys_getch +80104660 holding +801115d4 sb +80104700 acquire +8010684f vector226 +801021e0 nameiparent +801060f0 vector49 +801060c3 vector44 +801116a0 lapic +801061f5 vector78 +80105a4e alltraps +801065d3 vector173 +80106354 vector117 +80106219 vector82 +8010681f vector222 +80105f8d vector8 +801064b3 vector149 +801017f0 iupdate +80108000 data +801047c0 memset +80106897 vector232 +80103180 main +80106bf0 switchkvm +801062f1 vector106 +80106807 vector220 +80106261 vector90 +8010655b vector163 +801068af vector234 +80103060 log_write +80104440 acquiresleep +801051b0 sys_unlink +80106165 vector62 +80106018 vector25 +801066ff vector198 +8010636f vector120 +8010a48c _binary_entryother_start +80102730 kinit1 +801060f9 vector50 +80105fc0 vector15 +801064cb vector151 +80106222 vector83 +80106258 vector89 +8010624f vector88 +80105a00 sys_shutdown +80105b30 trap +801059b0 sys_uptime +8010661b vector179 +80106069 vector34 +801060d5 vector46 +801063ff vector134 +8010682b vector223 +80113ce0 idt +801067ef vector218 +80103a30 pinit +80106fb0 deallocuvm +80106843 vector225 +80102a10 lapicid +8010667b vector187 +80103bf0 growproc +801044e0 holdingsleep +801117a4 ncpu +80106045 vector30 +80103b00 userinit +801000d0 bread +801063ae vector127 +80103830 piperead +80113c80 ticks +801066b7 vector192 +8010657f vector166 +80100ad0 consoleinit +801061e3 vector76 +801061da vector75 +80102360 ideintr +801066db vector195 +801064bf vector150 +80106141 vector58 +80106957 vector248 +8010638a vector123 +80106297 vector96 +8010604e vector31 +8010673b vector203 +8010643b vector139 +801064e3 vector153 +80106567 vector164 +80104340 procdump +80106378 vector121 +80105ed0 uartputc +80105f72 vector5 +8010658b vector167 +801064fb vector155 +80106963 vector249 +801001f0 brelse +8010696f vector250 +80106393 vector124 +80106315 vector110 +80106747 vector204 +801018a0 ilock +80105660 sys_exec +80106423 vector137 +8010a460 _binary_initcode_start +801049db swtch +8010694b vector247 +80105ffd vector22 +8010672f vector202 +80106b60 seginit +80101b30 iunlockput +801061bf vector72 +80106126 vector55 +801063a5 vector126 +80106180 vector65 +80106033 vector28 +8010a506 _binary_entryother_end +801065a3 vector169 +801001b0 bwrite +801068a3 vector233 +80105b00 idtinit +80103ef0 exit +80105850 sys_wait +80105840 sys_exit +80102100 dirlink +0000002c _binary_initcode_size +8010649b vector147 +80104400 initsleeplock +801022e0 ideinit +80106d90 loaduvm +801062df vector104 +8010634b vector116 +80111d40 ptable +801025a0 ioapicenable +80104600 popcli +8010a008 vectors +8010610b vector52 +80105fd2 vector17 +80106657 vector184 +801049c0 strlen +80105750 sys_pipe +80101680 iinit +80103530 picinit +8010676b vector207 +80106d10 inituvm +8010669f vector190 +801068eb vector239 +80106285 vector94 +8010627c vector93 +80102de0 initlog +80106687 vector188 +801060e7 vector48 +80102400 iderw +801067fb vector219 +801064a7 vector148 +80106813 vector221 +801027a0 kalloc +8010f920 devsw +801058a0 sys_getpid +80106207 vector80 +801065bb vector171 +801064ef vector154 +8010607b vector36 +801035a0 pipealloc +801068bb vector235 +801062e8 vector105 +801055b0 sys_chdir +8010f980 icache +8010648f vector146 +801066ab vector191 +801062d6 vector103 +80105520 sys_mknod +80102a60 lapicstartap +80106c00 switchuvm +801045b0 pushcli +801026d0 kinit2 +80105fa4 vector11 +80105fb9 vector14 +801010f0 filestat diff --git a/kill.asm b/kill.asm new file mode 100644 index 0000000..5b40d7a --- /dev/null +++ b/kill.asm @@ -0,0 +1,1173 @@ + +_kill: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char **argv) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: 53 push %ebx + 10: bb 01 00 00 00 mov $0x1,%ebx + 15: 51 push %ecx + 16: 83 ec 08 sub $0x8,%esp + 19: 8b 31 mov (%ecx),%esi + 1b: 8b 79 04 mov 0x4(%ecx),%edi + int i; + + if (argc < 2) { + 1e: 83 fe 01 cmp $0x1,%esi + 21: 7e 27 jle 4a + 23: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 27: 90 nop + printf(2, "usage: kill pid...\n"); + exit(); + } + for (i = 1; i < argc; i++) { + kill(atoi(argv[i])); + 28: 83 ec 0c sub $0xc,%esp + 2b: ff 34 9f push (%edi,%ebx,4) + for (i = 1; i < argc; i++) { + 2e: 83 c3 01 add $0x1,%ebx + kill(atoi(argv[i])); + 31: e8 0a 02 00 00 call 240 + 36: 89 04 24 mov %eax,(%esp) + 39: e8 95 02 00 00 call 2d3 + for (i = 1; i < argc; i++) { + 3e: 83 c4 10 add $0x10,%esp + 41: 39 de cmp %ebx,%esi + 43: 75 e3 jne 28 + } + exit(); + 45: e8 69 02 00 00 call 2b3 + printf(2, "usage: kill pid...\n"); + 4a: 50 push %eax + 4b: 50 push %eax + 4c: 68 48 07 00 00 push $0x748 + 51: 6a 02 push $0x2 + 53: e8 c8 03 00 00 call 420 + exit(); + 58: e8 56 02 00 00 call 2b3 + 5d: 66 90 xchg %ax,%ax + 5f: 90 nop + +00000060 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 60: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 61: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 63: 89 e5 mov %esp,%ebp + 65: 53 push %ebx + 66: 8b 4d 08 mov 0x8(%ebp),%ecx + 69: 8b 5d 0c mov 0xc(%ebp),%ebx + 6c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 70: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 74: 88 14 01 mov %dl,(%ecx,%eax,1) + 77: 83 c0 01 add $0x1,%eax + 7a: 84 d2 test %dl,%dl + 7c: 75 f2 jne 70 + ; + } + return os; +} + 7e: 8b 5d fc mov -0x4(%ebp),%ebx + 81: 89 c8 mov %ecx,%eax + 83: c9 leave + 84: c3 ret + 85: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 8c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000090 : + +int strcmp(const char *p, const char *q) { + 90: 55 push %ebp + 91: 89 e5 mov %esp,%ebp + 93: 53 push %ebx + 94: 8b 55 08 mov 0x8(%ebp),%edx + 97: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 9a: 0f b6 02 movzbl (%edx),%eax + 9d: 84 c0 test %al,%al + 9f: 75 17 jne b8 + a1: eb 3a jmp dd + a3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + a7: 90 nop + a8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + ac: 83 c2 01 add $0x1,%edx + af: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + b2: 84 c0 test %al,%al + b4: 74 1a je d0 + p++, q++; + b6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + b8: 0f b6 19 movzbl (%ecx),%ebx + bb: 38 c3 cmp %al,%bl + bd: 74 e9 je a8 + } + return (uchar) * p - (uchar) * q; + bf: 29 d8 sub %ebx,%eax +} + c1: 8b 5d fc mov -0x4(%ebp),%ebx + c4: c9 leave + c5: c3 ret + c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + cd: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + d0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + d4: 31 c0 xor %eax,%eax + d6: 29 d8 sub %ebx,%eax +} + d8: 8b 5d fc mov -0x4(%ebp),%ebx + db: c9 leave + dc: c3 ret + return (uchar) * p - (uchar) * q; + dd: 0f b6 19 movzbl (%ecx),%ebx + e0: 31 c0 xor %eax,%eax + e2: eb db jmp bf + e4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + eb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + ef: 90 nop + +000000f0 : + +uint strlen(const char *s) { + f0: 55 push %ebp + f1: 89 e5 mov %esp,%ebp + f3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + f6: 80 3a 00 cmpb $0x0,(%edx) + f9: 74 15 je 110 + fb: 31 c0 xor %eax,%eax + fd: 8d 76 00 lea 0x0(%esi),%esi + 100: 83 c0 01 add $0x1,%eax + 103: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 107: 89 c1 mov %eax,%ecx + 109: 75 f5 jne 100 + ; + } + return n; +} + 10b: 89 c8 mov %ecx,%eax + 10d: 5d pop %ebp + 10e: c3 ret + 10f: 90 nop + for (n = 0; s[n]; n++) { + 110: 31 c9 xor %ecx,%ecx +} + 112: 5d pop %ebp + 113: 89 c8 mov %ecx,%eax + 115: c3 ret + 116: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 11d: 8d 76 00 lea 0x0(%esi),%esi + +00000120 : + +void* memset(void *dst, int c, uint n) { + 120: 55 push %ebp + 121: 89 e5 mov %esp,%ebp + 123: 57 push %edi + 124: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 127: 8b 4d 10 mov 0x10(%ebp),%ecx + 12a: 8b 45 0c mov 0xc(%ebp),%eax + 12d: 89 d7 mov %edx,%edi + 12f: fc cld + 130: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 132: 8b 7d fc mov -0x4(%ebp),%edi + 135: 89 d0 mov %edx,%eax + 137: c9 leave + 138: c3 ret + 139: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000140 : + +char* strchr(const char *s, char c) { + 140: 55 push %ebp + 141: 89 e5 mov %esp,%ebp + 143: 8b 45 08 mov 0x8(%ebp),%eax + 146: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 14a: 0f b6 10 movzbl (%eax),%edx + 14d: 84 d2 test %dl,%dl + 14f: 75 12 jne 163 + 151: eb 1d jmp 170 + 153: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 157: 90 nop + 158: 0f b6 50 01 movzbl 0x1(%eax),%edx + 15c: 83 c0 01 add $0x1,%eax + 15f: 84 d2 test %dl,%dl + 161: 74 0d je 170 + if (*s == c) { + 163: 38 d1 cmp %dl,%cl + 165: 75 f1 jne 158 + return (char*)s; + } + } + return 0; +} + 167: 5d pop %ebp + 168: c3 ret + 169: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 170: 31 c0 xor %eax,%eax +} + 172: 5d pop %ebp + 173: c3 ret + 174: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 17b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 17f: 90 nop + +00000180 : + +char* gets(char *buf, int max) { + 180: 55 push %ebp + 181: 89 e5 mov %esp,%ebp + 183: 57 push %edi + 184: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 185: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 188: 53 push %ebx + for (i = 0; i + 1 < max;) { + 189: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 18b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 18e: eb 27 jmp 1b7 + cc = read(0, &c, 1); + 190: 83 ec 04 sub $0x4,%esp + 193: 6a 01 push $0x1 + 195: 57 push %edi + 196: 6a 00 push $0x0 + 198: e8 2e 01 00 00 call 2cb + if (cc < 1) { + 19d: 83 c4 10 add $0x10,%esp + 1a0: 85 c0 test %eax,%eax + 1a2: 7e 1d jle 1c1 + break; + } + buf[i++] = c; + 1a4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 1a8: 8b 55 08 mov 0x8(%ebp),%edx + 1ab: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 1af: 3c 0a cmp $0xa,%al + 1b1: 74 1d je 1d0 + 1b3: 3c 0d cmp $0xd,%al + 1b5: 74 19 je 1d0 + for (i = 0; i + 1 < max;) { + 1b7: 89 de mov %ebx,%esi + 1b9: 83 c3 01 add $0x1,%ebx + 1bc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1bf: 7c cf jl 190 + break; + } + } + buf[i] = '\0'; + 1c1: 8b 45 08 mov 0x8(%ebp),%eax + 1c4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1c8: 8d 65 f4 lea -0xc(%ebp),%esp + 1cb: 5b pop %ebx + 1cc: 5e pop %esi + 1cd: 5f pop %edi + 1ce: 5d pop %ebp + 1cf: c3 ret + buf[i] = '\0'; + 1d0: 8b 45 08 mov 0x8(%ebp),%eax + 1d3: 89 de mov %ebx,%esi + 1d5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 1d9: 8d 65 f4 lea -0xc(%ebp),%esp + 1dc: 5b pop %ebx + 1dd: 5e pop %esi + 1de: 5f pop %edi + 1df: 5d pop %ebp + 1e0: c3 ret + 1e1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1e8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ef: 90 nop + +000001f0 : + +int stat(const char *n, struct stat *st) { + 1f0: 55 push %ebp + 1f1: 89 e5 mov %esp,%ebp + 1f3: 56 push %esi + 1f4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 1f5: 83 ec 08 sub $0x8,%esp + 1f8: 6a 00 push $0x0 + 1fa: ff 75 08 push 0x8(%ebp) + 1fd: e8 19 01 00 00 call 31b + if (fd < 0) { + 202: 83 c4 10 add $0x10,%esp + 205: 85 c0 test %eax,%eax + 207: 78 27 js 230 + return -1; + } + r = fstat(fd, st); + 209: 83 ec 08 sub $0x8,%esp + 20c: ff 75 0c push 0xc(%ebp) + 20f: 89 c3 mov %eax,%ebx + 211: 50 push %eax + 212: e8 cc 00 00 00 call 2e3 + close(fd); + 217: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 21a: 89 c6 mov %eax,%esi + close(fd); + 21c: e8 2a 01 00 00 call 34b + return r; + 221: 83 c4 10 add $0x10,%esp +} + 224: 8d 65 f8 lea -0x8(%ebp),%esp + 227: 89 f0 mov %esi,%eax + 229: 5b pop %ebx + 22a: 5e pop %esi + 22b: 5d pop %ebp + 22c: c3 ret + 22d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 230: be ff ff ff ff mov $0xffffffff,%esi + 235: eb ed jmp 224 + 237: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 23e: 66 90 xchg %ax,%ax + +00000240 : + +int atoi(const char *s) { + 240: 55 push %ebp + 241: 89 e5 mov %esp,%ebp + 243: 53 push %ebx + 244: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 247: 0f be 02 movsbl (%edx),%eax + 24a: 8d 48 d0 lea -0x30(%eax),%ecx + 24d: 80 f9 09 cmp $0x9,%cl + n = 0; + 250: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 255: 77 1e ja 275 + 257: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 25e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 260: 83 c2 01 add $0x1,%edx + 263: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 266: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 26a: 0f be 02 movsbl (%edx),%eax + 26d: 8d 58 d0 lea -0x30(%eax),%ebx + 270: 80 fb 09 cmp $0x9,%bl + 273: 76 eb jbe 260 + } + return n; +} + 275: 8b 5d fc mov -0x4(%ebp),%ebx + 278: 89 c8 mov %ecx,%eax + 27a: c9 leave + 27b: c3 ret + 27c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000280 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 280: 55 push %ebp + 281: 89 e5 mov %esp,%ebp + 283: 57 push %edi + 284: 8b 45 10 mov 0x10(%ebp),%eax + 287: 8b 55 08 mov 0x8(%ebp),%edx + 28a: 56 push %esi + 28b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 28e: 85 c0 test %eax,%eax + 290: 7e 13 jle 2a5 + 292: 01 d0 add %edx,%eax + dst = vdst; + 294: 89 d7 mov %edx,%edi + 296: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 29d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 2a0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 2a1: 39 f8 cmp %edi,%eax + 2a3: 75 fb jne 2a0 + } + return vdst; +} + 2a5: 5e pop %esi + 2a6: 89 d0 mov %edx,%eax + 2a8: 5f pop %edi + 2a9: 5d pop %ebp + 2aa: c3 ret + +000002ab : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 2ab: b8 01 00 00 00 mov $0x1,%eax + 2b0: cd 40 int $0x40 + 2b2: c3 ret + +000002b3 : +SYSCALL(exit) + 2b3: b8 02 00 00 00 mov $0x2,%eax + 2b8: cd 40 int $0x40 + 2ba: c3 ret + +000002bb : +SYSCALL(wait) + 2bb: b8 03 00 00 00 mov $0x3,%eax + 2c0: cd 40 int $0x40 + 2c2: c3 ret + +000002c3 : +SYSCALL(pipe) + 2c3: b8 04 00 00 00 mov $0x4,%eax + 2c8: cd 40 int $0x40 + 2ca: c3 ret + +000002cb : +SYSCALL(read) + 2cb: b8 05 00 00 00 mov $0x5,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(kill) + 2d3: b8 06 00 00 00 mov $0x6,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(exec) + 2db: b8 07 00 00 00 mov $0x7,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(fstat) + 2e3: b8 08 00 00 00 mov $0x8,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(chdir) + 2eb: b8 09 00 00 00 mov $0x9,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(dup) + 2f3: b8 0a 00 00 00 mov $0xa,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(getpid) + 2fb: b8 0b 00 00 00 mov $0xb,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(sbrk) + 303: b8 0c 00 00 00 mov $0xc,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(sleep) + 30b: b8 0d 00 00 00 mov $0xd,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(uptime) + 313: b8 0e 00 00 00 mov $0xe,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(open) + 31b: b8 0f 00 00 00 mov $0xf,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(write) + 323: b8 10 00 00 00 mov $0x10,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(mknod) + 32b: b8 11 00 00 00 mov $0x11,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(unlink) + 333: b8 12 00 00 00 mov $0x12,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(link) + 33b: b8 13 00 00 00 mov $0x13,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(mkdir) + 343: b8 14 00 00 00 mov $0x14,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(close) + 34b: b8 15 00 00 00 mov $0x15,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(getch) + 353: b8 16 00 00 00 mov $0x16,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(greeting) + 35b: b8 17 00 00 00 mov $0x17,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(shutdown) + 363: b8 18 00 00 00 mov $0x18,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + 36b: 66 90 xchg %ax,%ax + 36d: 66 90 xchg %ax,%ax + 36f: 90 nop + +00000370 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 370: 55 push %ebp + 371: 89 e5 mov %esp,%ebp + 373: 57 push %edi + 374: 56 push %esi + 375: 53 push %ebx + 376: 83 ec 3c sub $0x3c,%esp + 379: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 37c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 37e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 381: 85 d2 test %edx,%edx + 383: 0f 89 7f 00 00 00 jns 408 + 389: f6 45 08 01 testb $0x1,0x8(%ebp) + 38d: 74 79 je 408 + neg = 1; + 38f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 396: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 398: 31 db xor %ebx,%ebx + 39a: 8d 75 d7 lea -0x29(%ebp),%esi + 39d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 3a0: 89 c8 mov %ecx,%eax + 3a2: 31 d2 xor %edx,%edx + 3a4: 89 cf mov %ecx,%edi + 3a6: f7 75 c4 divl -0x3c(%ebp) + 3a9: 0f b6 92 bc 07 00 00 movzbl 0x7bc(%edx),%edx + 3b0: 89 45 c0 mov %eax,-0x40(%ebp) + 3b3: 89 d8 mov %ebx,%eax + 3b5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3b8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3bb: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3be: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3c1: 76 dd jbe 3a0 + if (neg) { + 3c3: 8b 4d bc mov -0x44(%ebp),%ecx + 3c6: 85 c9 test %ecx,%ecx + 3c8: 74 0c je 3d6 + buf[i++] = '-'; + 3ca: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3cf: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 3d1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 3d6: 8b 7d b8 mov -0x48(%ebp),%edi + 3d9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 3dd: eb 07 jmp 3e6 + 3df: 90 nop + putc(fd, buf[i]); + 3e0: 0f b6 13 movzbl (%ebx),%edx + 3e3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 3e6: 83 ec 04 sub $0x4,%esp + 3e9: 88 55 d7 mov %dl,-0x29(%ebp) + 3ec: 6a 01 push $0x1 + 3ee: 56 push %esi + 3ef: 57 push %edi + 3f0: e8 2e ff ff ff call 323 + while (--i >= 0) { + 3f5: 83 c4 10 add $0x10,%esp + 3f8: 39 de cmp %ebx,%esi + 3fa: 75 e4 jne 3e0 + } +} + 3fc: 8d 65 f4 lea -0xc(%ebp),%esp + 3ff: 5b pop %ebx + 400: 5e pop %esi + 401: 5f pop %edi + 402: 5d pop %ebp + 403: c3 ret + 404: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 408: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 40f: eb 87 jmp 398 + 411: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 418: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 41f: 90 nop + +00000420 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 420: 55 push %ebp + 421: 89 e5 mov %esp,%ebp + 423: 57 push %edi + 424: 56 push %esi + 425: 53 push %ebx + 426: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 429: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 42c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 42f: 0f b6 13 movzbl (%ebx),%edx + 432: 84 d2 test %dl,%dl + 434: 74 6a je 4a0 + ap = (uint*)(void*)&fmt + 1; + 436: 8d 45 10 lea 0x10(%ebp),%eax + 439: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 43c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 43f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 441: 89 45 d0 mov %eax,-0x30(%ebp) + 444: eb 36 jmp 47c + 446: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 44d: 8d 76 00 lea 0x0(%esi),%esi + 450: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 453: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 458: 83 f8 25 cmp $0x25,%eax + 45b: 74 15 je 472 + write(fd, &c, 1); + 45d: 83 ec 04 sub $0x4,%esp + 460: 88 55 e7 mov %dl,-0x19(%ebp) + 463: 6a 01 push $0x1 + 465: 57 push %edi + 466: 56 push %esi + 467: e8 b7 fe ff ff call 323 + 46c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 46f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 472: 0f b6 13 movzbl (%ebx),%edx + 475: 83 c3 01 add $0x1,%ebx + 478: 84 d2 test %dl,%dl + 47a: 74 24 je 4a0 + c = fmt[i] & 0xff; + 47c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 47f: 85 c9 test %ecx,%ecx + 481: 74 cd je 450 + } + } + else if (state == '%') { + 483: 83 f9 25 cmp $0x25,%ecx + 486: 75 ea jne 472 + if (c == 'd') { + 488: 83 f8 25 cmp $0x25,%eax + 48b: 0f 84 07 01 00 00 je 598 + 491: 83 e8 63 sub $0x63,%eax + 494: 83 f8 15 cmp $0x15,%eax + 497: 77 17 ja 4b0 + 499: ff 24 85 64 07 00 00 jmp *0x764(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 4a0: 8d 65 f4 lea -0xc(%ebp),%esp + 4a3: 5b pop %ebx + 4a4: 5e pop %esi + 4a5: 5f pop %edi + 4a6: 5d pop %ebp + 4a7: c3 ret + 4a8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4af: 90 nop + write(fd, &c, 1); + 4b0: 83 ec 04 sub $0x4,%esp + 4b3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4b6: 6a 01 push $0x1 + 4b8: 57 push %edi + 4b9: 56 push %esi + 4ba: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4be: e8 60 fe ff ff call 323 + putc(fd, c); + 4c3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4c7: 83 c4 0c add $0xc,%esp + 4ca: 88 55 e7 mov %dl,-0x19(%ebp) + 4cd: 6a 01 push $0x1 + 4cf: 57 push %edi + 4d0: 56 push %esi + 4d1: e8 4d fe ff ff call 323 + putc(fd, c); + 4d6: 83 c4 10 add $0x10,%esp + state = 0; + 4d9: 31 c9 xor %ecx,%ecx + 4db: eb 95 jmp 472 + 4dd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 4e0: 83 ec 0c sub $0xc,%esp + 4e3: b9 10 00 00 00 mov $0x10,%ecx + 4e8: 6a 00 push $0x0 + 4ea: 8b 45 d0 mov -0x30(%ebp),%eax + 4ed: 8b 10 mov (%eax),%edx + 4ef: 89 f0 mov %esi,%eax + 4f1: e8 7a fe ff ff call 370 + ap++; + 4f6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 4fa: 83 c4 10 add $0x10,%esp + state = 0; + 4fd: 31 c9 xor %ecx,%ecx + 4ff: e9 6e ff ff ff jmp 472 + 504: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 508: 8b 45 d0 mov -0x30(%ebp),%eax + 50b: 8b 10 mov (%eax),%edx + ap++; + 50d: 83 c0 04 add $0x4,%eax + 510: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 513: 85 d2 test %edx,%edx + 515: 0f 84 8d 00 00 00 je 5a8 + while (*s != 0) { + 51b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 51e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 520: 84 c0 test %al,%al + 522: 0f 84 4a ff ff ff je 472 + 528: 89 5d d4 mov %ebx,-0x2c(%ebp) + 52b: 89 d3 mov %edx,%ebx + 52d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 530: 83 ec 04 sub $0x4,%esp + s++; + 533: 83 c3 01 add $0x1,%ebx + 536: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 539: 6a 01 push $0x1 + 53b: 57 push %edi + 53c: 56 push %esi + 53d: e8 e1 fd ff ff call 323 + while (*s != 0) { + 542: 0f b6 03 movzbl (%ebx),%eax + 545: 83 c4 10 add $0x10,%esp + 548: 84 c0 test %al,%al + 54a: 75 e4 jne 530 + state = 0; + 54c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 54f: 31 c9 xor %ecx,%ecx + 551: e9 1c ff ff ff jmp 472 + 556: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 55d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 560: 83 ec 0c sub $0xc,%esp + 563: b9 0a 00 00 00 mov $0xa,%ecx + 568: 6a 01 push $0x1 + 56a: e9 7b ff ff ff jmp 4ea + 56f: 90 nop + putc(fd, *ap); + 570: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 573: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 576: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 578: 6a 01 push $0x1 + 57a: 57 push %edi + 57b: 56 push %esi + putc(fd, *ap); + 57c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 57f: e8 9f fd ff ff call 323 + ap++; + 584: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 588: 83 c4 10 add $0x10,%esp + state = 0; + 58b: 31 c9 xor %ecx,%ecx + 58d: e9 e0 fe ff ff jmp 472 + 592: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 598: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 59b: 83 ec 04 sub $0x4,%esp + 59e: e9 2a ff ff ff jmp 4cd + 5a3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 5a7: 90 nop + s = "(null)"; + 5a8: ba 5c 07 00 00 mov $0x75c,%edx + while (*s != 0) { + 5ad: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5b0: b8 28 00 00 00 mov $0x28,%eax + 5b5: 89 d3 mov %edx,%ebx + 5b7: e9 74 ff ff ff jmp 530 + 5bc: 66 90 xchg %ax,%ax + 5be: 66 90 xchg %ax,%ax + +000005c0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5c0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5c1: a1 74 0a 00 00 mov 0xa74,%eax +void free(void *ap) { + 5c6: 89 e5 mov %esp,%ebp + 5c8: 57 push %edi + 5c9: 56 push %esi + 5ca: 53 push %ebx + 5cb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5ce: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5d1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5d8: 89 c2 mov %eax,%edx + 5da: 8b 00 mov (%eax),%eax + 5dc: 39 ca cmp %ecx,%edx + 5de: 73 30 jae 610 + 5e0: 39 c1 cmp %eax,%ecx + 5e2: 72 04 jb 5e8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 5e4: 39 c2 cmp %eax,%edx + 5e6: 72 f0 jb 5d8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 5e8: 8b 73 fc mov -0x4(%ebx),%esi + 5eb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 5ee: 39 f8 cmp %edi,%eax + 5f0: 74 30 je 622 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 5f2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 5f5: 8b 42 04 mov 0x4(%edx),%eax + 5f8: 8d 34 c2 lea (%edx,%eax,8),%esi + 5fb: 39 f1 cmp %esi,%ecx + 5fd: 74 3a je 639 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 5ff: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 601: 5b pop %ebx + freep = p; + 602: 89 15 74 0a 00 00 mov %edx,0xa74 +} + 608: 5e pop %esi + 609: 5f pop %edi + 60a: 5d pop %ebp + 60b: c3 ret + 60c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 610: 39 c2 cmp %eax,%edx + 612: 72 c4 jb 5d8 + 614: 39 c1 cmp %eax,%ecx + 616: 73 c0 jae 5d8 + if (bp + bp->s.size == p->s.ptr) { + 618: 8b 73 fc mov -0x4(%ebx),%esi + 61b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 61e: 39 f8 cmp %edi,%eax + 620: 75 d0 jne 5f2 + bp->s.size += p->s.ptr->s.size; + 622: 03 70 04 add 0x4(%eax),%esi + 625: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 628: 8b 02 mov (%edx),%eax + 62a: 8b 00 mov (%eax),%eax + 62c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 62f: 8b 42 04 mov 0x4(%edx),%eax + 632: 8d 34 c2 lea (%edx,%eax,8),%esi + 635: 39 f1 cmp %esi,%ecx + 637: 75 c6 jne 5ff + p->s.size += bp->s.size; + 639: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 63c: 89 15 74 0a 00 00 mov %edx,0xa74 + p->s.size += bp->s.size; + 642: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 645: 8b 4b f8 mov -0x8(%ebx),%ecx + 648: 89 0a mov %ecx,(%edx) +} + 64a: 5b pop %ebx + 64b: 5e pop %esi + 64c: 5f pop %edi + 64d: 5d pop %ebp + 64e: c3 ret + 64f: 90 nop + +00000650 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 650: 55 push %ebp + 651: 89 e5 mov %esp,%ebp + 653: 57 push %edi + 654: 56 push %esi + 655: 53 push %ebx + 656: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 659: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 65c: 8b 3d 74 0a 00 00 mov 0xa74,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 662: 8d 70 07 lea 0x7(%eax),%esi + 665: c1 ee 03 shr $0x3,%esi + 668: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 66b: 85 ff test %edi,%edi + 66d: 0f 84 9d 00 00 00 je 710 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 673: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 675: 8b 4a 04 mov 0x4(%edx),%ecx + 678: 39 f1 cmp %esi,%ecx + 67a: 73 6a jae 6e6 + 67c: bb 00 10 00 00 mov $0x1000,%ebx + 681: 39 de cmp %ebx,%esi + 683: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 686: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 68d: 89 45 e4 mov %eax,-0x1c(%ebp) + 690: eb 17 jmp 6a9 + 692: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 698: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 69a: 8b 48 04 mov 0x4(%eax),%ecx + 69d: 39 f1 cmp %esi,%ecx + 69f: 73 4f jae 6f0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 6a1: 8b 3d 74 0a 00 00 mov 0xa74,%edi + 6a7: 89 c2 mov %eax,%edx + 6a9: 39 d7 cmp %edx,%edi + 6ab: 75 eb jne 698 + p = sbrk(nu * sizeof(Header)); + 6ad: 83 ec 0c sub $0xc,%esp + 6b0: ff 75 e4 push -0x1c(%ebp) + 6b3: e8 4b fc ff ff call 303 + if (p == (char*)-1) { + 6b8: 83 c4 10 add $0x10,%esp + 6bb: 83 f8 ff cmp $0xffffffff,%eax + 6be: 74 1c je 6dc + hp->s.size = nu; + 6c0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6c3: 83 ec 0c sub $0xc,%esp + 6c6: 83 c0 08 add $0x8,%eax + 6c9: 50 push %eax + 6ca: e8 f1 fe ff ff call 5c0 + return freep; + 6cf: 8b 15 74 0a 00 00 mov 0xa74,%edx + if ((p = morecore(nunits)) == 0) { + 6d5: 83 c4 10 add $0x10,%esp + 6d8: 85 d2 test %edx,%edx + 6da: 75 bc jne 698 + return 0; + } + } + } +} + 6dc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 6df: 31 c0 xor %eax,%eax +} + 6e1: 5b pop %ebx + 6e2: 5e pop %esi + 6e3: 5f pop %edi + 6e4: 5d pop %ebp + 6e5: c3 ret + if (p->s.size >= nunits) { + 6e6: 89 d0 mov %edx,%eax + 6e8: 89 fa mov %edi,%edx + 6ea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 6f0: 39 ce cmp %ecx,%esi + 6f2: 74 4c je 740 + p->s.size -= nunits; + 6f4: 29 f1 sub %esi,%ecx + 6f6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 6f9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 6fc: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 6ff: 89 15 74 0a 00 00 mov %edx,0xa74 +} + 705: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 708: 83 c0 08 add $0x8,%eax +} + 70b: 5b pop %ebx + 70c: 5e pop %esi + 70d: 5f pop %edi + 70e: 5d pop %ebp + 70f: c3 ret + base.s.ptr = freep = prevp = &base; + 710: c7 05 74 0a 00 00 78 movl $0xa78,0xa74 + 717: 0a 00 00 + base.s.size = 0; + 71a: bf 78 0a 00 00 mov $0xa78,%edi + base.s.ptr = freep = prevp = &base; + 71f: c7 05 78 0a 00 00 78 movl $0xa78,0xa78 + 726: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 729: 89 fa mov %edi,%edx + base.s.size = 0; + 72b: c7 05 7c 0a 00 00 00 movl $0x0,0xa7c + 732: 00 00 00 + if (p->s.size >= nunits) { + 735: e9 42 ff ff ff jmp 67c + 73a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 740: 8b 08 mov (%eax),%ecx + 742: 89 0a mov %ecx,(%edx) + 744: eb b9 jmp 6ff diff --git a/kill.c b/kill.c new file mode 100644 index 0000000..bcca9a9 --- /dev/null +++ b/kill.c @@ -0,0 +1,16 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char **argv) { + int i; + + if (argc < 2) { + printf(2, "usage: kill pid...\n"); + exit(); + } + for (i = 1; i < argc; i++) { + kill(atoi(argv[i])); + } + exit(); +} diff --git a/kill.d b/kill.d new file mode 100644 index 0000000..078f4f8 --- /dev/null +++ b/kill.d @@ -0,0 +1 @@ +kill.o: kill.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/kill.o b/kill.o new file mode 100644 index 0000000..f84f644 Binary files /dev/null and b/kill.o differ diff --git a/kill.sym b/kill.sym new file mode 100644 index 0000000..ed3d956 --- /dev/null +++ b/kill.sym @@ -0,0 +1,48 @@ +00000000 kill.c +00000000 ulib.c +00000000 printf.c +00000370 printint +000007bc digits.0 +00000000 umalloc.c +00000a74 freep +00000a78 base +00000060 strcpy +00000420 printf +0000035b greeting +00000280 memmove +0000032b mknod +00000180 gets +000002fb getpid +00000650 malloc +0000030b sleep +000002c3 pipe +00000353 getch +00000323 write +000002e3 fstat +000002d3 kill +000002eb chdir +000002db exec +000002bb wait +000002cb read +00000333 unlink +000002ab fork +00000303 sbrk +00000313 uptime +00000a74 __bss_start +00000120 memset +00000000 main +00000090 strcmp +00000363 shutdown +000002f3 dup +000001f0 stat +00000a74 _edata +00000a80 _end +0000033b link +000002b3 exit +00000240 atoi +000000f0 strlen +0000031b open +00000140 strchr +00000343 mkdir +0000034b close +000005c0 free diff --git a/lapic.c b/lapic.c new file mode 100644 index 0000000..946db80 --- /dev/null +++ b/lapic.c @@ -0,0 +1,218 @@ +// The local APIC manages internal (non-I/O) interrupts. +// See Chapter 8 & Appendix C of Intel processor manual volume 3. + +#include "param.h" +#include "types.h" +#include "defs.h" +#include "date.h" +#include "memlayout.h" +#include "traps.h" +#include "mmu.h" +#include "x86.h" + +// Local APIC registers, divided by 4 for use as uint[] indices. +#define ID (0x0020 / 4) // ID +#define VER (0x0030 / 4) // Version +#define TPR (0x0080 / 4) // Task Priority +#define EOI (0x00B0 / 4) // EOI +#define SVR (0x00F0 / 4) // Spurious Interrupt Vector + #define ENABLE 0x00000100 // Unit Enable +#define ESR (0x0280 / 4) // Error Status +#define ICRLO (0x0300 / 4) // Interrupt Command + #define INIT 0x00000500 // INIT/RESET + #define STARTUP 0x00000600 // Startup IPI + #define DELIVS 0x00001000 // Delivery status + #define ASSERT 0x00004000 // Assert interrupt (vs deassert) + #define DEASSERT 0x00000000 + #define LEVEL 0x00008000 // Level triggered + #define BCAST 0x00080000 // Send to all APICs, including self. + #define BUSY 0x00001000 + #define FIXED 0x00000000 +#define ICRHI (0x0310 / 4) // Interrupt Command [63:32] +#define TIMER (0x0320 / 4) // Local Vector Table 0 (TIMER) + #define X1 0x0000000B // divide counts by 1 + #define PERIODIC 0x00020000 // Periodic +#define PCINT (0x0340 / 4) // Performance Counter LVT +#define LINT0 (0x0350 / 4) // Local Vector Table 1 (LINT0) +#define LINT1 (0x0360 / 4) // Local Vector Table 2 (LINT1) +#define ERROR (0x0370 / 4) // Local Vector Table 3 (ERROR) + #define MASKED 0x00010000 // Interrupt masked +#define TICR (0x0380 / 4) // Timer Initial Count +#define TCCR (0x0390 / 4) // Timer Current Count +#define TDCR (0x03E0 / 4) // Timer Divide Configuration + +volatile uint *lapic; // Initialized in mp.c + + +static void lapicw(int index, int value) { + lapic[index] = value; + lapic[ID]; // wait for write to finish, by reading +} + +void lapicinit(void) { + if (!lapic) { + return; + } + + // Enable local APIC; set spurious interrupt vector. + lapicw(SVR, ENABLE | (T_IRQ0 + IRQ_SPURIOUS)); + + // The timer repeatedly counts down at bus frequency + // from lapic[TICR] and then issues an interrupt. + // If xv6 cared more about precise timekeeping, + // TICR would be calibrated using an external time source. + lapicw(TDCR, X1); + lapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER)); + lapicw(TICR, 10000000); + + // Disable logical interrupt lines. + lapicw(LINT0, MASKED); + lapicw(LINT1, MASKED); + + // Disable performance counter overflow interrupts + // on machines that provide that interrupt entry. + if (((lapic[VER] >> 16) & 0xFF) >= 4) { + lapicw(PCINT, MASKED); + } + + // Map error interrupt to IRQ_ERROR. + lapicw(ERROR, T_IRQ0 + IRQ_ERROR); + + // Clear error status register (requires back-to-back writes). + lapicw(ESR, 0); + lapicw(ESR, 0); + + // Ack any outstanding interrupts. + lapicw(EOI, 0); + + // Send an Init Level De-Assert to synchronise arbitration ID's. + lapicw(ICRHI, 0); + lapicw(ICRLO, BCAST | INIT | LEVEL); + while (lapic[ICRLO] & DELIVS) { + ; + } + + // Enable interrupts on the APIC (but not on the processor). + lapicw(TPR, 0); +} + +int lapicid(void) { + if (!lapic) { + return 0; + } + return lapic[ID] >> 24; +} + +// Acknowledge interrupt. +void lapiceoi(void) { + if (lapic) { + lapicw(EOI, 0); + } +} + +// Spin for a given number of microseconds. +// On real hardware would want to tune this dynamically. +void microdelay(int us) { +} + +#define CMOS_PORT 0x70 +#define CMOS_RETURN 0x71 + +// Start additional processor running entry code at addr. +// See Appendix B of MultiProcessor Specification. +void lapicstartap(uchar apicid, uint addr) { + int i; + ushort *wrv; + + // "The BSP must initialize CMOS shutdown code to 0AH + // and the warm reset vector (DWORD based at 40:67) to point at + // the AP startup code prior to the [universal startup algorithm]." + outb(CMOS_PORT, 0xF); // offset 0xF is shutdown code + outb(CMOS_PORT + 1, 0x0A); + wrv = (ushort*)P2V((0x40 << 4 | 0x67)); // Warm reset vector + wrv[0] = 0; + wrv[1] = addr >> 4; + + // "Universal startup algorithm." + // Send INIT (level-triggered) interrupt to reset other CPU. + lapicw(ICRHI, apicid << 24); + lapicw(ICRLO, INIT | LEVEL | ASSERT); + microdelay(200); + lapicw(ICRLO, INIT | LEVEL); + microdelay(100); // should be 10ms, but too slow in Bochs! + + // Send startup IPI (twice!) to enter code. + // Regular hardware is supposed to only accept a STARTUP + // when it is in the halted state due to an INIT. So the second + // should be ignored, but it is part of the official Intel algorithm. + // Bochs complains about the second one. Too bad for Bochs. + for (i = 0; i < 2; i++) { + lapicw(ICRHI, apicid << 24); + lapicw(ICRLO, STARTUP | (addr >> 12)); + microdelay(200); + } +} + +#define CMOS_STATA 0x0a +#define CMOS_STATB 0x0b +#define CMOS_UIP (1 << 7) // RTC update in progress + +#define SECS 0x00 +#define MINS 0x02 +#define HOURS 0x04 +#define DAY 0x07 +#define MONTH 0x08 +#define YEAR 0x09 + +static uint cmos_read(uint reg) { + outb(CMOS_PORT, reg); + microdelay(200); + + return inb(CMOS_RETURN); +} + +static void fill_rtcdate(struct rtcdate *r) { + r->second = cmos_read(SECS); + r->minute = cmos_read(MINS); + r->hour = cmos_read(HOURS); + r->day = cmos_read(DAY); + r->month = cmos_read(MONTH); + r->year = cmos_read(YEAR); +} + +// qemu seems to use 24-hour GWT and the values are BCD encoded +void cmostime(struct rtcdate *r) { + struct rtcdate t1, t2; + int sb, bcd; + + sb = cmos_read(CMOS_STATB); + + bcd = (sb & (1 << 2)) == 0; + + // make sure CMOS doesn't modify time while we read it + for (;;) { + fill_rtcdate(&t1); + if (cmos_read(CMOS_STATA) & CMOS_UIP) { + continue; + } + fill_rtcdate(&t2); + if (memcmp(&t1, &t2, sizeof(t1)) == 0) { + break; + } + } + + // convert + if (bcd) { +#define CONV(x) (t1.x = ((t1.x >> 4) * 10) + (t1.x & 0xf)) + CONV(second); + CONV(minute); + CONV(hour ); + CONV(day ); + CONV(month ); + CONV(year ); +#undef CONV + } + + *r = t1; + r->year += 2000; +} diff --git a/lapic.d b/lapic.d new file mode 100644 index 0000000..6e62387 --- /dev/null +++ b/lapic.d @@ -0,0 +1,2 @@ +lapic.o: lapic.c /usr/include/stdc-predef.h param.h types.h defs.h date.h \ + memlayout.h traps.h mmu.h x86.h diff --git a/lapic.o b/lapic.o new file mode 100644 index 0000000..04f46de Binary files /dev/null and b/lapic.o differ diff --git a/ln.asm b/ln.asm new file mode 100644 index 0000000..723336c --- /dev/null +++ b/ln.asm @@ -0,0 +1,1169 @@ + +_ln: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + if (argc != 3) { + a: 83 39 03 cmpl $0x3,(%ecx) +int main(int argc, char *argv[]) { + d: 55 push %ebp + e: 89 e5 mov %esp,%ebp + 10: 53 push %ebx + 11: 51 push %ecx + 12: 8b 59 04 mov 0x4(%ecx),%ebx + if (argc != 3) { + 15: 74 13 je 2a + printf(2, "Usage: ln old new\n"); + 17: 52 push %edx + 18: 52 push %edx + 19: 68 48 07 00 00 push $0x748 + 1e: 6a 02 push $0x2 + 20: e8 fb 03 00 00 call 420 + exit(); + 25: e8 89 02 00 00 call 2b3 + } + if (link(argv[1], argv[2]) < 0) { + 2a: 50 push %eax + 2b: 50 push %eax + 2c: ff 73 08 push 0x8(%ebx) + 2f: ff 73 04 push 0x4(%ebx) + 32: e8 04 03 00 00 call 33b + 37: 83 c4 10 add $0x10,%esp + 3a: 85 c0 test %eax,%eax + 3c: 78 05 js 43 + printf(2, "link %s %s: failed\n", argv[1], argv[2]); + } + exit(); + 3e: e8 70 02 00 00 call 2b3 + printf(2, "link %s %s: failed\n", argv[1], argv[2]); + 43: ff 73 08 push 0x8(%ebx) + 46: ff 73 04 push 0x4(%ebx) + 49: 68 5b 07 00 00 push $0x75b + 4e: 6a 02 push $0x2 + 50: e8 cb 03 00 00 call 420 + 55: 83 c4 10 add $0x10,%esp + 58: eb e4 jmp 3e + 5a: 66 90 xchg %ax,%ax + 5c: 66 90 xchg %ax,%ax + 5e: 66 90 xchg %ax,%ax + +00000060 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 60: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 61: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 63: 89 e5 mov %esp,%ebp + 65: 53 push %ebx + 66: 8b 4d 08 mov 0x8(%ebp),%ecx + 69: 8b 5d 0c mov 0xc(%ebp),%ebx + 6c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 70: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 74: 88 14 01 mov %dl,(%ecx,%eax,1) + 77: 83 c0 01 add $0x1,%eax + 7a: 84 d2 test %dl,%dl + 7c: 75 f2 jne 70 + ; + } + return os; +} + 7e: 8b 5d fc mov -0x4(%ebp),%ebx + 81: 89 c8 mov %ecx,%eax + 83: c9 leave + 84: c3 ret + 85: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 8c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000090 : + +int strcmp(const char *p, const char *q) { + 90: 55 push %ebp + 91: 89 e5 mov %esp,%ebp + 93: 53 push %ebx + 94: 8b 55 08 mov 0x8(%ebp),%edx + 97: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 9a: 0f b6 02 movzbl (%edx),%eax + 9d: 84 c0 test %al,%al + 9f: 75 17 jne b8 + a1: eb 3a jmp dd + a3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + a7: 90 nop + a8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + ac: 83 c2 01 add $0x1,%edx + af: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + b2: 84 c0 test %al,%al + b4: 74 1a je d0 + p++, q++; + b6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + b8: 0f b6 19 movzbl (%ecx),%ebx + bb: 38 c3 cmp %al,%bl + bd: 74 e9 je a8 + } + return (uchar) * p - (uchar) * q; + bf: 29 d8 sub %ebx,%eax +} + c1: 8b 5d fc mov -0x4(%ebp),%ebx + c4: c9 leave + c5: c3 ret + c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + cd: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + d0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + d4: 31 c0 xor %eax,%eax + d6: 29 d8 sub %ebx,%eax +} + d8: 8b 5d fc mov -0x4(%ebp),%ebx + db: c9 leave + dc: c3 ret + return (uchar) * p - (uchar) * q; + dd: 0f b6 19 movzbl (%ecx),%ebx + e0: 31 c0 xor %eax,%eax + e2: eb db jmp bf + e4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + eb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + ef: 90 nop + +000000f0 : + +uint strlen(const char *s) { + f0: 55 push %ebp + f1: 89 e5 mov %esp,%ebp + f3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + f6: 80 3a 00 cmpb $0x0,(%edx) + f9: 74 15 je 110 + fb: 31 c0 xor %eax,%eax + fd: 8d 76 00 lea 0x0(%esi),%esi + 100: 83 c0 01 add $0x1,%eax + 103: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 107: 89 c1 mov %eax,%ecx + 109: 75 f5 jne 100 + ; + } + return n; +} + 10b: 89 c8 mov %ecx,%eax + 10d: 5d pop %ebp + 10e: c3 ret + 10f: 90 nop + for (n = 0; s[n]; n++) { + 110: 31 c9 xor %ecx,%ecx +} + 112: 5d pop %ebp + 113: 89 c8 mov %ecx,%eax + 115: c3 ret + 116: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 11d: 8d 76 00 lea 0x0(%esi),%esi + +00000120 : + +void* memset(void *dst, int c, uint n) { + 120: 55 push %ebp + 121: 89 e5 mov %esp,%ebp + 123: 57 push %edi + 124: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 127: 8b 4d 10 mov 0x10(%ebp),%ecx + 12a: 8b 45 0c mov 0xc(%ebp),%eax + 12d: 89 d7 mov %edx,%edi + 12f: fc cld + 130: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 132: 8b 7d fc mov -0x4(%ebp),%edi + 135: 89 d0 mov %edx,%eax + 137: c9 leave + 138: c3 ret + 139: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000140 : + +char* strchr(const char *s, char c) { + 140: 55 push %ebp + 141: 89 e5 mov %esp,%ebp + 143: 8b 45 08 mov 0x8(%ebp),%eax + 146: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 14a: 0f b6 10 movzbl (%eax),%edx + 14d: 84 d2 test %dl,%dl + 14f: 75 12 jne 163 + 151: eb 1d jmp 170 + 153: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 157: 90 nop + 158: 0f b6 50 01 movzbl 0x1(%eax),%edx + 15c: 83 c0 01 add $0x1,%eax + 15f: 84 d2 test %dl,%dl + 161: 74 0d je 170 + if (*s == c) { + 163: 38 d1 cmp %dl,%cl + 165: 75 f1 jne 158 + return (char*)s; + } + } + return 0; +} + 167: 5d pop %ebp + 168: c3 ret + 169: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 170: 31 c0 xor %eax,%eax +} + 172: 5d pop %ebp + 173: c3 ret + 174: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 17b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 17f: 90 nop + +00000180 : + +char* gets(char *buf, int max) { + 180: 55 push %ebp + 181: 89 e5 mov %esp,%ebp + 183: 57 push %edi + 184: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 185: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 188: 53 push %ebx + for (i = 0; i + 1 < max;) { + 189: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 18b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 18e: eb 27 jmp 1b7 + cc = read(0, &c, 1); + 190: 83 ec 04 sub $0x4,%esp + 193: 6a 01 push $0x1 + 195: 57 push %edi + 196: 6a 00 push $0x0 + 198: e8 2e 01 00 00 call 2cb + if (cc < 1) { + 19d: 83 c4 10 add $0x10,%esp + 1a0: 85 c0 test %eax,%eax + 1a2: 7e 1d jle 1c1 + break; + } + buf[i++] = c; + 1a4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 1a8: 8b 55 08 mov 0x8(%ebp),%edx + 1ab: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 1af: 3c 0a cmp $0xa,%al + 1b1: 74 1d je 1d0 + 1b3: 3c 0d cmp $0xd,%al + 1b5: 74 19 je 1d0 + for (i = 0; i + 1 < max;) { + 1b7: 89 de mov %ebx,%esi + 1b9: 83 c3 01 add $0x1,%ebx + 1bc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1bf: 7c cf jl 190 + break; + } + } + buf[i] = '\0'; + 1c1: 8b 45 08 mov 0x8(%ebp),%eax + 1c4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1c8: 8d 65 f4 lea -0xc(%ebp),%esp + 1cb: 5b pop %ebx + 1cc: 5e pop %esi + 1cd: 5f pop %edi + 1ce: 5d pop %ebp + 1cf: c3 ret + buf[i] = '\0'; + 1d0: 8b 45 08 mov 0x8(%ebp),%eax + 1d3: 89 de mov %ebx,%esi + 1d5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 1d9: 8d 65 f4 lea -0xc(%ebp),%esp + 1dc: 5b pop %ebx + 1dd: 5e pop %esi + 1de: 5f pop %edi + 1df: 5d pop %ebp + 1e0: c3 ret + 1e1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1e8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ef: 90 nop + +000001f0 : + +int stat(const char *n, struct stat *st) { + 1f0: 55 push %ebp + 1f1: 89 e5 mov %esp,%ebp + 1f3: 56 push %esi + 1f4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 1f5: 83 ec 08 sub $0x8,%esp + 1f8: 6a 00 push $0x0 + 1fa: ff 75 08 push 0x8(%ebp) + 1fd: e8 19 01 00 00 call 31b + if (fd < 0) { + 202: 83 c4 10 add $0x10,%esp + 205: 85 c0 test %eax,%eax + 207: 78 27 js 230 + return -1; + } + r = fstat(fd, st); + 209: 83 ec 08 sub $0x8,%esp + 20c: ff 75 0c push 0xc(%ebp) + 20f: 89 c3 mov %eax,%ebx + 211: 50 push %eax + 212: e8 cc 00 00 00 call 2e3 + close(fd); + 217: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 21a: 89 c6 mov %eax,%esi + close(fd); + 21c: e8 2a 01 00 00 call 34b + return r; + 221: 83 c4 10 add $0x10,%esp +} + 224: 8d 65 f8 lea -0x8(%ebp),%esp + 227: 89 f0 mov %esi,%eax + 229: 5b pop %ebx + 22a: 5e pop %esi + 22b: 5d pop %ebp + 22c: c3 ret + 22d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 230: be ff ff ff ff mov $0xffffffff,%esi + 235: eb ed jmp 224 + 237: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 23e: 66 90 xchg %ax,%ax + +00000240 : + +int atoi(const char *s) { + 240: 55 push %ebp + 241: 89 e5 mov %esp,%ebp + 243: 53 push %ebx + 244: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 247: 0f be 02 movsbl (%edx),%eax + 24a: 8d 48 d0 lea -0x30(%eax),%ecx + 24d: 80 f9 09 cmp $0x9,%cl + n = 0; + 250: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 255: 77 1e ja 275 + 257: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 25e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 260: 83 c2 01 add $0x1,%edx + 263: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 266: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 26a: 0f be 02 movsbl (%edx),%eax + 26d: 8d 58 d0 lea -0x30(%eax),%ebx + 270: 80 fb 09 cmp $0x9,%bl + 273: 76 eb jbe 260 + } + return n; +} + 275: 8b 5d fc mov -0x4(%ebp),%ebx + 278: 89 c8 mov %ecx,%eax + 27a: c9 leave + 27b: c3 ret + 27c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000280 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 280: 55 push %ebp + 281: 89 e5 mov %esp,%ebp + 283: 57 push %edi + 284: 8b 45 10 mov 0x10(%ebp),%eax + 287: 8b 55 08 mov 0x8(%ebp),%edx + 28a: 56 push %esi + 28b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 28e: 85 c0 test %eax,%eax + 290: 7e 13 jle 2a5 + 292: 01 d0 add %edx,%eax + dst = vdst; + 294: 89 d7 mov %edx,%edi + 296: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 29d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 2a0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 2a1: 39 f8 cmp %edi,%eax + 2a3: 75 fb jne 2a0 + } + return vdst; +} + 2a5: 5e pop %esi + 2a6: 89 d0 mov %edx,%eax + 2a8: 5f pop %edi + 2a9: 5d pop %ebp + 2aa: c3 ret + +000002ab : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 2ab: b8 01 00 00 00 mov $0x1,%eax + 2b0: cd 40 int $0x40 + 2b2: c3 ret + +000002b3 : +SYSCALL(exit) + 2b3: b8 02 00 00 00 mov $0x2,%eax + 2b8: cd 40 int $0x40 + 2ba: c3 ret + +000002bb : +SYSCALL(wait) + 2bb: b8 03 00 00 00 mov $0x3,%eax + 2c0: cd 40 int $0x40 + 2c2: c3 ret + +000002c3 : +SYSCALL(pipe) + 2c3: b8 04 00 00 00 mov $0x4,%eax + 2c8: cd 40 int $0x40 + 2ca: c3 ret + +000002cb : +SYSCALL(read) + 2cb: b8 05 00 00 00 mov $0x5,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(kill) + 2d3: b8 06 00 00 00 mov $0x6,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(exec) + 2db: b8 07 00 00 00 mov $0x7,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(fstat) + 2e3: b8 08 00 00 00 mov $0x8,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(chdir) + 2eb: b8 09 00 00 00 mov $0x9,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(dup) + 2f3: b8 0a 00 00 00 mov $0xa,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(getpid) + 2fb: b8 0b 00 00 00 mov $0xb,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(sbrk) + 303: b8 0c 00 00 00 mov $0xc,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(sleep) + 30b: b8 0d 00 00 00 mov $0xd,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(uptime) + 313: b8 0e 00 00 00 mov $0xe,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(open) + 31b: b8 0f 00 00 00 mov $0xf,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(write) + 323: b8 10 00 00 00 mov $0x10,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(mknod) + 32b: b8 11 00 00 00 mov $0x11,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(unlink) + 333: b8 12 00 00 00 mov $0x12,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(link) + 33b: b8 13 00 00 00 mov $0x13,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(mkdir) + 343: b8 14 00 00 00 mov $0x14,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(close) + 34b: b8 15 00 00 00 mov $0x15,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(getch) + 353: b8 16 00 00 00 mov $0x16,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(greeting) + 35b: b8 17 00 00 00 mov $0x17,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(shutdown) + 363: b8 18 00 00 00 mov $0x18,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + 36b: 66 90 xchg %ax,%ax + 36d: 66 90 xchg %ax,%ax + 36f: 90 nop + +00000370 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 370: 55 push %ebp + 371: 89 e5 mov %esp,%ebp + 373: 57 push %edi + 374: 56 push %esi + 375: 53 push %ebx + 376: 83 ec 3c sub $0x3c,%esp + 379: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 37c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 37e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 381: 85 d2 test %edx,%edx + 383: 0f 89 7f 00 00 00 jns 408 + 389: f6 45 08 01 testb $0x1,0x8(%ebp) + 38d: 74 79 je 408 + neg = 1; + 38f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 396: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 398: 31 db xor %ebx,%ebx + 39a: 8d 75 d7 lea -0x29(%ebp),%esi + 39d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 3a0: 89 c8 mov %ecx,%eax + 3a2: 31 d2 xor %edx,%edx + 3a4: 89 cf mov %ecx,%edi + 3a6: f7 75 c4 divl -0x3c(%ebp) + 3a9: 0f b6 92 d0 07 00 00 movzbl 0x7d0(%edx),%edx + 3b0: 89 45 c0 mov %eax,-0x40(%ebp) + 3b3: 89 d8 mov %ebx,%eax + 3b5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3b8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3bb: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3be: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3c1: 76 dd jbe 3a0 + if (neg) { + 3c3: 8b 4d bc mov -0x44(%ebp),%ecx + 3c6: 85 c9 test %ecx,%ecx + 3c8: 74 0c je 3d6 + buf[i++] = '-'; + 3ca: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3cf: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 3d1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 3d6: 8b 7d b8 mov -0x48(%ebp),%edi + 3d9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 3dd: eb 07 jmp 3e6 + 3df: 90 nop + putc(fd, buf[i]); + 3e0: 0f b6 13 movzbl (%ebx),%edx + 3e3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 3e6: 83 ec 04 sub $0x4,%esp + 3e9: 88 55 d7 mov %dl,-0x29(%ebp) + 3ec: 6a 01 push $0x1 + 3ee: 56 push %esi + 3ef: 57 push %edi + 3f0: e8 2e ff ff ff call 323 + while (--i >= 0) { + 3f5: 83 c4 10 add $0x10,%esp + 3f8: 39 de cmp %ebx,%esi + 3fa: 75 e4 jne 3e0 + } +} + 3fc: 8d 65 f4 lea -0xc(%ebp),%esp + 3ff: 5b pop %ebx + 400: 5e pop %esi + 401: 5f pop %edi + 402: 5d pop %ebp + 403: c3 ret + 404: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 408: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 40f: eb 87 jmp 398 + 411: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 418: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 41f: 90 nop + +00000420 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 420: 55 push %ebp + 421: 89 e5 mov %esp,%ebp + 423: 57 push %edi + 424: 56 push %esi + 425: 53 push %ebx + 426: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 429: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 42c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 42f: 0f b6 13 movzbl (%ebx),%edx + 432: 84 d2 test %dl,%dl + 434: 74 6a je 4a0 + ap = (uint*)(void*)&fmt + 1; + 436: 8d 45 10 lea 0x10(%ebp),%eax + 439: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 43c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 43f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 441: 89 45 d0 mov %eax,-0x30(%ebp) + 444: eb 36 jmp 47c + 446: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 44d: 8d 76 00 lea 0x0(%esi),%esi + 450: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 453: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 458: 83 f8 25 cmp $0x25,%eax + 45b: 74 15 je 472 + write(fd, &c, 1); + 45d: 83 ec 04 sub $0x4,%esp + 460: 88 55 e7 mov %dl,-0x19(%ebp) + 463: 6a 01 push $0x1 + 465: 57 push %edi + 466: 56 push %esi + 467: e8 b7 fe ff ff call 323 + 46c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 46f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 472: 0f b6 13 movzbl (%ebx),%edx + 475: 83 c3 01 add $0x1,%ebx + 478: 84 d2 test %dl,%dl + 47a: 74 24 je 4a0 + c = fmt[i] & 0xff; + 47c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 47f: 85 c9 test %ecx,%ecx + 481: 74 cd je 450 + } + } + else if (state == '%') { + 483: 83 f9 25 cmp $0x25,%ecx + 486: 75 ea jne 472 + if (c == 'd') { + 488: 83 f8 25 cmp $0x25,%eax + 48b: 0f 84 07 01 00 00 je 598 + 491: 83 e8 63 sub $0x63,%eax + 494: 83 f8 15 cmp $0x15,%eax + 497: 77 17 ja 4b0 + 499: ff 24 85 78 07 00 00 jmp *0x778(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 4a0: 8d 65 f4 lea -0xc(%ebp),%esp + 4a3: 5b pop %ebx + 4a4: 5e pop %esi + 4a5: 5f pop %edi + 4a6: 5d pop %ebp + 4a7: c3 ret + 4a8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4af: 90 nop + write(fd, &c, 1); + 4b0: 83 ec 04 sub $0x4,%esp + 4b3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4b6: 6a 01 push $0x1 + 4b8: 57 push %edi + 4b9: 56 push %esi + 4ba: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4be: e8 60 fe ff ff call 323 + putc(fd, c); + 4c3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4c7: 83 c4 0c add $0xc,%esp + 4ca: 88 55 e7 mov %dl,-0x19(%ebp) + 4cd: 6a 01 push $0x1 + 4cf: 57 push %edi + 4d0: 56 push %esi + 4d1: e8 4d fe ff ff call 323 + putc(fd, c); + 4d6: 83 c4 10 add $0x10,%esp + state = 0; + 4d9: 31 c9 xor %ecx,%ecx + 4db: eb 95 jmp 472 + 4dd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 4e0: 83 ec 0c sub $0xc,%esp + 4e3: b9 10 00 00 00 mov $0x10,%ecx + 4e8: 6a 00 push $0x0 + 4ea: 8b 45 d0 mov -0x30(%ebp),%eax + 4ed: 8b 10 mov (%eax),%edx + 4ef: 89 f0 mov %esi,%eax + 4f1: e8 7a fe ff ff call 370 + ap++; + 4f6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 4fa: 83 c4 10 add $0x10,%esp + state = 0; + 4fd: 31 c9 xor %ecx,%ecx + 4ff: e9 6e ff ff ff jmp 472 + 504: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 508: 8b 45 d0 mov -0x30(%ebp),%eax + 50b: 8b 10 mov (%eax),%edx + ap++; + 50d: 83 c0 04 add $0x4,%eax + 510: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 513: 85 d2 test %edx,%edx + 515: 0f 84 8d 00 00 00 je 5a8 + while (*s != 0) { + 51b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 51e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 520: 84 c0 test %al,%al + 522: 0f 84 4a ff ff ff je 472 + 528: 89 5d d4 mov %ebx,-0x2c(%ebp) + 52b: 89 d3 mov %edx,%ebx + 52d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 530: 83 ec 04 sub $0x4,%esp + s++; + 533: 83 c3 01 add $0x1,%ebx + 536: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 539: 6a 01 push $0x1 + 53b: 57 push %edi + 53c: 56 push %esi + 53d: e8 e1 fd ff ff call 323 + while (*s != 0) { + 542: 0f b6 03 movzbl (%ebx),%eax + 545: 83 c4 10 add $0x10,%esp + 548: 84 c0 test %al,%al + 54a: 75 e4 jne 530 + state = 0; + 54c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 54f: 31 c9 xor %ecx,%ecx + 551: e9 1c ff ff ff jmp 472 + 556: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 55d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 560: 83 ec 0c sub $0xc,%esp + 563: b9 0a 00 00 00 mov $0xa,%ecx + 568: 6a 01 push $0x1 + 56a: e9 7b ff ff ff jmp 4ea + 56f: 90 nop + putc(fd, *ap); + 570: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 573: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 576: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 578: 6a 01 push $0x1 + 57a: 57 push %edi + 57b: 56 push %esi + putc(fd, *ap); + 57c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 57f: e8 9f fd ff ff call 323 + ap++; + 584: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 588: 83 c4 10 add $0x10,%esp + state = 0; + 58b: 31 c9 xor %ecx,%ecx + 58d: e9 e0 fe ff ff jmp 472 + 592: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 598: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 59b: 83 ec 04 sub $0x4,%esp + 59e: e9 2a ff ff ff jmp 4cd + 5a3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 5a7: 90 nop + s = "(null)"; + 5a8: ba 6f 07 00 00 mov $0x76f,%edx + while (*s != 0) { + 5ad: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5b0: b8 28 00 00 00 mov $0x28,%eax + 5b5: 89 d3 mov %edx,%ebx + 5b7: e9 74 ff ff ff jmp 530 + 5bc: 66 90 xchg %ax,%ax + 5be: 66 90 xchg %ax,%ax + +000005c0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5c0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5c1: a1 7c 0a 00 00 mov 0xa7c,%eax +void free(void *ap) { + 5c6: 89 e5 mov %esp,%ebp + 5c8: 57 push %edi + 5c9: 56 push %esi + 5ca: 53 push %ebx + 5cb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5ce: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5d1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5d8: 89 c2 mov %eax,%edx + 5da: 8b 00 mov (%eax),%eax + 5dc: 39 ca cmp %ecx,%edx + 5de: 73 30 jae 610 + 5e0: 39 c1 cmp %eax,%ecx + 5e2: 72 04 jb 5e8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 5e4: 39 c2 cmp %eax,%edx + 5e6: 72 f0 jb 5d8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 5e8: 8b 73 fc mov -0x4(%ebx),%esi + 5eb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 5ee: 39 f8 cmp %edi,%eax + 5f0: 74 30 je 622 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 5f2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 5f5: 8b 42 04 mov 0x4(%edx),%eax + 5f8: 8d 34 c2 lea (%edx,%eax,8),%esi + 5fb: 39 f1 cmp %esi,%ecx + 5fd: 74 3a je 639 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 5ff: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 601: 5b pop %ebx + freep = p; + 602: 89 15 7c 0a 00 00 mov %edx,0xa7c +} + 608: 5e pop %esi + 609: 5f pop %edi + 60a: 5d pop %ebp + 60b: c3 ret + 60c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 610: 39 c2 cmp %eax,%edx + 612: 72 c4 jb 5d8 + 614: 39 c1 cmp %eax,%ecx + 616: 73 c0 jae 5d8 + if (bp + bp->s.size == p->s.ptr) { + 618: 8b 73 fc mov -0x4(%ebx),%esi + 61b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 61e: 39 f8 cmp %edi,%eax + 620: 75 d0 jne 5f2 + bp->s.size += p->s.ptr->s.size; + 622: 03 70 04 add 0x4(%eax),%esi + 625: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 628: 8b 02 mov (%edx),%eax + 62a: 8b 00 mov (%eax),%eax + 62c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 62f: 8b 42 04 mov 0x4(%edx),%eax + 632: 8d 34 c2 lea (%edx,%eax,8),%esi + 635: 39 f1 cmp %esi,%ecx + 637: 75 c6 jne 5ff + p->s.size += bp->s.size; + 639: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 63c: 89 15 7c 0a 00 00 mov %edx,0xa7c + p->s.size += bp->s.size; + 642: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 645: 8b 4b f8 mov -0x8(%ebx),%ecx + 648: 89 0a mov %ecx,(%edx) +} + 64a: 5b pop %ebx + 64b: 5e pop %esi + 64c: 5f pop %edi + 64d: 5d pop %ebp + 64e: c3 ret + 64f: 90 nop + +00000650 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 650: 55 push %ebp + 651: 89 e5 mov %esp,%ebp + 653: 57 push %edi + 654: 56 push %esi + 655: 53 push %ebx + 656: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 659: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 65c: 8b 3d 7c 0a 00 00 mov 0xa7c,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 662: 8d 70 07 lea 0x7(%eax),%esi + 665: c1 ee 03 shr $0x3,%esi + 668: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 66b: 85 ff test %edi,%edi + 66d: 0f 84 9d 00 00 00 je 710 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 673: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 675: 8b 4a 04 mov 0x4(%edx),%ecx + 678: 39 f1 cmp %esi,%ecx + 67a: 73 6a jae 6e6 + 67c: bb 00 10 00 00 mov $0x1000,%ebx + 681: 39 de cmp %ebx,%esi + 683: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 686: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 68d: 89 45 e4 mov %eax,-0x1c(%ebp) + 690: eb 17 jmp 6a9 + 692: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 698: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 69a: 8b 48 04 mov 0x4(%eax),%ecx + 69d: 39 f1 cmp %esi,%ecx + 69f: 73 4f jae 6f0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 6a1: 8b 3d 7c 0a 00 00 mov 0xa7c,%edi + 6a7: 89 c2 mov %eax,%edx + 6a9: 39 d7 cmp %edx,%edi + 6ab: 75 eb jne 698 + p = sbrk(nu * sizeof(Header)); + 6ad: 83 ec 0c sub $0xc,%esp + 6b0: ff 75 e4 push -0x1c(%ebp) + 6b3: e8 4b fc ff ff call 303 + if (p == (char*)-1) { + 6b8: 83 c4 10 add $0x10,%esp + 6bb: 83 f8 ff cmp $0xffffffff,%eax + 6be: 74 1c je 6dc + hp->s.size = nu; + 6c0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6c3: 83 ec 0c sub $0xc,%esp + 6c6: 83 c0 08 add $0x8,%eax + 6c9: 50 push %eax + 6ca: e8 f1 fe ff ff call 5c0 + return freep; + 6cf: 8b 15 7c 0a 00 00 mov 0xa7c,%edx + if ((p = morecore(nunits)) == 0) { + 6d5: 83 c4 10 add $0x10,%esp + 6d8: 85 d2 test %edx,%edx + 6da: 75 bc jne 698 + return 0; + } + } + } +} + 6dc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 6df: 31 c0 xor %eax,%eax +} + 6e1: 5b pop %ebx + 6e2: 5e pop %esi + 6e3: 5f pop %edi + 6e4: 5d pop %ebp + 6e5: c3 ret + if (p->s.size >= nunits) { + 6e6: 89 d0 mov %edx,%eax + 6e8: 89 fa mov %edi,%edx + 6ea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 6f0: 39 ce cmp %ecx,%esi + 6f2: 74 4c je 740 + p->s.size -= nunits; + 6f4: 29 f1 sub %esi,%ecx + 6f6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 6f9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 6fc: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 6ff: 89 15 7c 0a 00 00 mov %edx,0xa7c +} + 705: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 708: 83 c0 08 add $0x8,%eax +} + 70b: 5b pop %ebx + 70c: 5e pop %esi + 70d: 5f pop %edi + 70e: 5d pop %ebp + 70f: c3 ret + base.s.ptr = freep = prevp = &base; + 710: c7 05 7c 0a 00 00 80 movl $0xa80,0xa7c + 717: 0a 00 00 + base.s.size = 0; + 71a: bf 80 0a 00 00 mov $0xa80,%edi + base.s.ptr = freep = prevp = &base; + 71f: c7 05 80 0a 00 00 80 movl $0xa80,0xa80 + 726: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 729: 89 fa mov %edi,%edx + base.s.size = 0; + 72b: c7 05 84 0a 00 00 00 movl $0x0,0xa84 + 732: 00 00 00 + if (p->s.size >= nunits) { + 735: e9 42 ff ff ff jmp 67c + 73a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 740: 8b 08 mov (%eax),%ecx + 742: 89 0a mov %ecx,(%edx) + 744: eb b9 jmp 6ff diff --git a/ln.c b/ln.c new file mode 100644 index 0000000..8883514 --- /dev/null +++ b/ln.c @@ -0,0 +1,14 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + if (argc != 3) { + printf(2, "Usage: ln old new\n"); + exit(); + } + if (link(argv[1], argv[2]) < 0) { + printf(2, "link %s %s: failed\n", argv[1], argv[2]); + } + exit(); +} diff --git a/ln.d b/ln.d new file mode 100644 index 0000000..6728be9 --- /dev/null +++ b/ln.d @@ -0,0 +1 @@ +ln.o: ln.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/ln.o b/ln.o new file mode 100644 index 0000000..ac99f39 Binary files /dev/null and b/ln.o differ diff --git a/ln.sym b/ln.sym new file mode 100644 index 0000000..0c48f49 --- /dev/null +++ b/ln.sym @@ -0,0 +1,48 @@ +00000000 ln.c +00000000 ulib.c +00000000 printf.c +00000370 printint +000007d0 digits.0 +00000000 umalloc.c +00000a7c freep +00000a80 base +00000060 strcpy +00000420 printf +0000035b greeting +00000280 memmove +0000032b mknod +00000180 gets +000002fb getpid +00000650 malloc +0000030b sleep +000002c3 pipe +00000353 getch +00000323 write +000002e3 fstat +000002d3 kill +000002eb chdir +000002db exec +000002bb wait +000002cb read +00000333 unlink +000002ab fork +00000303 sbrk +00000313 uptime +00000a7c __bss_start +00000120 memset +00000000 main +00000090 strcmp +00000363 shutdown +000002f3 dup +000001f0 stat +00000a7c _edata +00000a88 _end +0000033b link +000002b3 exit +00000240 atoi +000000f0 strlen +0000031b open +00000140 strchr +00000343 mkdir +0000034b close +000005c0 free diff --git a/log.c b/log.c new file mode 100644 index 0000000..a64c0f6 --- /dev/null +++ b/log.c @@ -0,0 +1,234 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "fs.h" +#include "buf.h" + +// Simple logging that allows concurrent FS system calls. +// +// A log transaction contains the updates of multiple FS system +// calls. The logging system only commits when there are +// no FS system calls active. Thus there is never +// any reasoning required about whether a commit might +// write an uncommitted system call's updates to disk. +// +// A system call should call begin_op()/end_op() to mark +// its start and end. Usually begin_op() just increments +// the count of in-progress FS system calls and returns. +// But if it thinks the log is close to running out, it +// sleeps until the last outstanding end_op() commits. +// +// The log is a physical re-do log containing disk blocks. +// The on-disk log format: +// header block, containing block #s for block A, B, C, ... +// block A +// block B +// block C +// ... +// Log appends are synchronous. + +// Contents of the header block, used for both the on-disk header block +// and to keep track in memory of logged block# before commit. +struct logheader { + int n; + int block[LOGSIZE]; +}; + +struct log { + struct spinlock lock; + int start; + int size; + int outstanding; // how many FS sys calls are executing. + int committing; // in commit(), please wait. + int dev; + struct logheader lh; +}; +struct log log; + +static void recover_from_log(void); +static void commit(); + +void +initlog(int dev) +{ + if (sizeof(struct logheader) >= BSIZE) + panic("initlog: too big logheader"); + + struct superblock sb; + initlock(&log.lock, "log"); + readsb(dev, &sb); + log.start = sb.logstart; + log.size = sb.nlog; + log.dev = dev; + recover_from_log(); +} + +// Copy committed blocks from log to their home location +static void +install_trans(void) +{ + int tail; + + for (tail = 0; tail < log.lh.n; tail++) { + struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block + struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst + memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst + bwrite(dbuf); // write dst to disk + brelse(lbuf); + brelse(dbuf); + } +} + +// Read the log header from disk into the in-memory log header +static void +read_head(void) +{ + struct buf *buf = bread(log.dev, log.start); + struct logheader *lh = (struct logheader *) (buf->data); + int i; + log.lh.n = lh->n; + for (i = 0; i < log.lh.n; i++) { + log.lh.block[i] = lh->block[i]; + } + brelse(buf); +} + +// Write in-memory log header to disk. +// This is the true point at which the +// current transaction commits. +static void +write_head(void) +{ + struct buf *buf = bread(log.dev, log.start); + struct logheader *hb = (struct logheader *) (buf->data); + int i; + hb->n = log.lh.n; + for (i = 0; i < log.lh.n; i++) { + hb->block[i] = log.lh.block[i]; + } + bwrite(buf); + brelse(buf); +} + +static void +recover_from_log(void) +{ + read_head(); + install_trans(); // if committed, copy from log to disk + log.lh.n = 0; + write_head(); // clear the log +} + +// called at the start of each FS system call. +void +begin_op(void) +{ + acquire(&log.lock); + while(1){ + if(log.committing){ + sleep(&log, &log.lock); + } else if(log.lh.n + (log.outstanding+1)*MAXOPBLOCKS > LOGSIZE){ + // this op might exhaust log space; wait for commit. + sleep(&log, &log.lock); + } else { + log.outstanding += 1; + release(&log.lock); + break; + } + } +} + +// called at the end of each FS system call. +// commits if this was the last outstanding operation. +void +end_op(void) +{ + int do_commit = 0; + + acquire(&log.lock); + log.outstanding -= 1; + if(log.committing) + panic("log.committing"); + if(log.outstanding == 0){ + do_commit = 1; + log.committing = 1; + } else { + // begin_op() may be waiting for log space, + // and decrementing log.outstanding has decreased + // the amount of reserved space. + wakeup(&log); + } + release(&log.lock); + + if(do_commit){ + // call commit w/o holding locks, since not allowed + // to sleep with locks. + commit(); + acquire(&log.lock); + log.committing = 0; + wakeup(&log); + release(&log.lock); + } +} + +// Copy modified blocks from cache to log. +static void +write_log(void) +{ + int tail; + + for (tail = 0; tail < log.lh.n; tail++) { + struct buf *to = bread(log.dev, log.start+tail+1); // log block + struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block + memmove(to->data, from->data, BSIZE); + bwrite(to); // write the log + brelse(from); + brelse(to); + } +} + +static void +commit() +{ + if (log.lh.n > 0) { + write_log(); // Write modified blocks from cache to log + write_head(); // Write header to disk -- the real commit + install_trans(); // Now install writes to home locations + log.lh.n = 0; + write_head(); // Erase the transaction from the log + } +} + +// Caller has modified b->data and is done with the buffer. +// Record the block number and pin in the cache with B_DIRTY. +// commit()/write_log() will do the disk write. +// +// log_write() replaces bwrite(); a typical use is: +// bp = bread(...) +// modify bp->data[] +// log_write(bp) +// brelse(bp) +void +log_write(struct buf *b) +{ + int i; + + if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1) + panic("too big a transaction"); + if (log.outstanding < 1) + panic("log_write outside of trans"); + + acquire(&log.lock); + for (i = 0; i < log.lh.n; i++) { + if (log.lh.block[i] == b->blockno) // log absorbtion + break; + } + log.lh.block[i] = b->blockno; + if (i == log.lh.n) + log.lh.n++; + b->flags |= B_DIRTY; // prevent eviction + release(&log.lock); +} + diff --git a/log.d b/log.d new file mode 100644 index 0000000..04c8930 --- /dev/null +++ b/log.d @@ -0,0 +1,2 @@ +log.o: log.c /usr/include/stdc-predef.h types.h defs.h param.h spinlock.h \ + sleeplock.h fs.h buf.h diff --git a/log.o b/log.o new file mode 100644 index 0000000..bb71507 Binary files /dev/null and b/log.o differ diff --git a/ls.asm b/ls.asm new file mode 100644 index 0000000..e8c2a47 --- /dev/null +++ b/ls.asm @@ -0,0 +1,1454 @@ + +_ls: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: + close(fd); +} + +int +main(int argc, char *argv[]) +{ + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: 53 push %ebx + 10: bb 01 00 00 00 mov $0x1,%ebx + 15: 51 push %ecx + 16: 83 ec 08 sub $0x8,%esp + 19: 8b 31 mov (%ecx),%esi + 1b: 8b 79 04 mov 0x4(%ecx),%edi + int i; + + if(argc < 2){ + 1e: 83 fe 01 cmp $0x1,%esi + 21: 7e 1f jle 42 + 23: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 27: 90 nop + ls("."); + exit(); + } + for(i=1; i + for(i=1; i + exit(); + 3d: e8 51 05 00 00 call 593 + ls("."); + 42: 83 ec 0c sub $0xc,%esp + 45: 68 70 0a 00 00 push $0xa70 + 4a: e8 b1 00 00 00 call 100 + exit(); + 4f: e8 3f 05 00 00 call 593 + 54: 66 90 xchg %ax,%ax + 56: 66 90 xchg %ax,%ax + 58: 66 90 xchg %ax,%ax + 5a: 66 90 xchg %ax,%ax + 5c: 66 90 xchg %ax,%ax + 5e: 66 90 xchg %ax,%ax + +00000060 : +{ + 60: 55 push %ebp + 61: 89 e5 mov %esp,%ebp + 63: 56 push %esi + 64: 53 push %ebx + 65: 8b 75 08 mov 0x8(%ebp),%esi + for(p=path+strlen(path); p >= path && *p != '/'; p--) + 68: 83 ec 0c sub $0xc,%esp + 6b: 56 push %esi + 6c: e8 5f 03 00 00 call 3d0 + 71: 83 c4 10 add $0x10,%esp + 74: 01 f0 add %esi,%eax + 76: 89 c3 mov %eax,%ebx + 78: 73 0f jae 89 + 7a: eb 12 jmp 8e + 7c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 80: 8d 43 ff lea -0x1(%ebx),%eax + 83: 39 c6 cmp %eax,%esi + 85: 77 0a ja 91 + 87: 89 c3 mov %eax,%ebx + 89: 80 3b 2f cmpb $0x2f,(%ebx) + 8c: 75 f2 jne 80 + p++; + 8e: 83 c3 01 add $0x1,%ebx + if(strlen(p) >= DIRSIZ) + 91: 83 ec 0c sub $0xc,%esp + 94: 53 push %ebx + 95: e8 36 03 00 00 call 3d0 + 9a: 83 c4 10 add $0x10,%esp + 9d: 83 f8 0d cmp $0xd,%eax + a0: 77 4a ja ec + memmove(buf, p, strlen(p)); + a2: 83 ec 0c sub $0xc,%esp + a5: 53 push %ebx + a6: e8 25 03 00 00 call 3d0 + ab: 83 c4 0c add $0xc,%esp + ae: 50 push %eax + af: 53 push %ebx + b0: 68 04 0e 00 00 push $0xe04 + b5: e8 a6 04 00 00 call 560 + memset(buf+strlen(p), ' ', DIRSIZ-strlen(p)); + ba: 89 1c 24 mov %ebx,(%esp) + bd: e8 0e 03 00 00 call 3d0 + c2: 89 1c 24 mov %ebx,(%esp) + return buf; + c5: bb 04 0e 00 00 mov $0xe04,%ebx + memset(buf+strlen(p), ' ', DIRSIZ-strlen(p)); + ca: 89 c6 mov %eax,%esi + cc: e8 ff 02 00 00 call 3d0 + d1: ba 0e 00 00 00 mov $0xe,%edx + d6: 83 c4 0c add $0xc,%esp + d9: 29 f2 sub %esi,%edx + db: 05 04 0e 00 00 add $0xe04,%eax + e0: 52 push %edx + e1: 6a 20 push $0x20 + e3: 50 push %eax + e4: e8 17 03 00 00 call 400 + return buf; + e9: 83 c4 10 add $0x10,%esp +} + ec: 8d 65 f8 lea -0x8(%ebp),%esp + ef: 89 d8 mov %ebx,%eax + f1: 5b pop %ebx + f2: 5e pop %esi + f3: 5d pop %ebp + f4: c3 ret + f5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + fc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000100 : +{ + 100: 55 push %ebp + 101: 89 e5 mov %esp,%ebp + 103: 57 push %edi + 104: 56 push %esi + 105: 53 push %ebx + 106: 81 ec 64 02 00 00 sub $0x264,%esp + 10c: 8b 7d 08 mov 0x8(%ebp),%edi + if((fd = open(path, 0)) < 0){ + 10f: 6a 00 push $0x0 + 111: 57 push %edi + 112: e8 e4 04 00 00 call 5fb + 117: 83 c4 10 add $0x10,%esp + 11a: 85 c0 test %eax,%eax + 11c: 0f 88 9e 01 00 00 js 2c0 + if(fstat(fd, &st) < 0){ + 122: 83 ec 08 sub $0x8,%esp + 125: 8d b5 d4 fd ff ff lea -0x22c(%ebp),%esi + 12b: 89 c3 mov %eax,%ebx + 12d: 56 push %esi + 12e: 50 push %eax + 12f: e8 8f 04 00 00 call 5c3 + 134: 83 c4 10 add $0x10,%esp + 137: 85 c0 test %eax,%eax + 139: 0f 88 c1 01 00 00 js 300 + switch(st.type){ + 13f: 0f b7 85 d4 fd ff ff movzwl -0x22c(%ebp),%eax + 146: 66 83 f8 01 cmp $0x1,%ax + 14a: 74 64 je 1b0 + 14c: 66 83 f8 02 cmp $0x2,%ax + 150: 74 1e je 170 + close(fd); + 152: 83 ec 0c sub $0xc,%esp + 155: 53 push %ebx + 156: e8 d0 04 00 00 call 62b + 15b: 83 c4 10 add $0x10,%esp +} + 15e: 8d 65 f4 lea -0xc(%ebp),%esp + 161: 5b pop %ebx + 162: 5e pop %esi + 163: 5f pop %edi + 164: 5d pop %ebp + 165: c3 ret + 166: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 16d: 8d 76 00 lea 0x0(%esi),%esi + printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size); + 170: 83 ec 0c sub $0xc,%esp + 173: 8b 95 e4 fd ff ff mov -0x21c(%ebp),%edx + 179: 8b b5 dc fd ff ff mov -0x224(%ebp),%esi + 17f: 57 push %edi + 180: 89 95 b4 fd ff ff mov %edx,-0x24c(%ebp) + 186: e8 d5 fe ff ff call 60 + 18b: 8b 95 b4 fd ff ff mov -0x24c(%ebp),%edx + 191: 59 pop %ecx + 192: 5f pop %edi + 193: 52 push %edx + 194: 56 push %esi + 195: 6a 02 push $0x2 + 197: 50 push %eax + 198: 68 50 0a 00 00 push $0xa50 + 19d: 6a 01 push $0x1 + 19f: e8 5c 05 00 00 call 700 + break; + 1a4: 83 c4 20 add $0x20,%esp + 1a7: eb a9 jmp 152 + 1a9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ + 1b0: 83 ec 0c sub $0xc,%esp + 1b3: 57 push %edi + 1b4: e8 17 02 00 00 call 3d0 + 1b9: 83 c4 10 add $0x10,%esp + 1bc: 83 c0 10 add $0x10,%eax + 1bf: 3d 00 02 00 00 cmp $0x200,%eax + 1c4: 0f 87 16 01 00 00 ja 2e0 + strcpy(buf, path); + 1ca: 83 ec 08 sub $0x8,%esp + 1cd: 57 push %edi + 1ce: 8d bd e8 fd ff ff lea -0x218(%ebp),%edi + 1d4: 57 push %edi + 1d5: e8 66 01 00 00 call 340 + p = buf+strlen(buf); + 1da: 89 3c 24 mov %edi,(%esp) + 1dd: e8 ee 01 00 00 call 3d0 + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + 1e2: 83 c4 10 add $0x10,%esp + p = buf+strlen(buf); + 1e5: 01 f8 add %edi,%eax + *p++ = '/'; + 1e7: 8d 48 01 lea 0x1(%eax),%ecx + p = buf+strlen(buf); + 1ea: 89 85 a8 fd ff ff mov %eax,-0x258(%ebp) + *p++ = '/'; + 1f0: 89 8d a4 fd ff ff mov %ecx,-0x25c(%ebp) + 1f6: c6 00 2f movb $0x2f,(%eax) + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + 1f9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 200: 83 ec 04 sub $0x4,%esp + 203: 8d 85 c4 fd ff ff lea -0x23c(%ebp),%eax + 209: 6a 10 push $0x10 + 20b: 50 push %eax + 20c: 53 push %ebx + 20d: e8 99 03 00 00 call 5ab + 212: 83 c4 10 add $0x10,%esp + 215: 83 f8 10 cmp $0x10,%eax + 218: 0f 85 34 ff ff ff jne 152 + if(de.inum == 0) + 21e: 66 83 bd c4 fd ff ff cmpw $0x0,-0x23c(%ebp) + 225: 00 + 226: 74 d8 je 200 + memmove(p, de.name, DIRSIZ); + 228: 83 ec 04 sub $0x4,%esp + 22b: 8d 85 c6 fd ff ff lea -0x23a(%ebp),%eax + 231: 6a 0e push $0xe + 233: 50 push %eax + 234: ff b5 a4 fd ff ff push -0x25c(%ebp) + 23a: e8 21 03 00 00 call 560 + p[DIRSIZ] = 0; + 23f: 8b 85 a8 fd ff ff mov -0x258(%ebp),%eax + 245: c6 40 0f 00 movb $0x0,0xf(%eax) + if(stat(buf, &st) < 0){ + 249: 58 pop %eax + 24a: 5a pop %edx + 24b: 56 push %esi + 24c: 57 push %edi + 24d: e8 7e 02 00 00 call 4d0 + 252: 83 c4 10 add $0x10,%esp + 255: 85 c0 test %eax,%eax + 257: 0f 88 cb 00 00 00 js 328 + printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size); + 25d: 83 ec 0c sub $0xc,%esp + 260: 8b 8d e4 fd ff ff mov -0x21c(%ebp),%ecx + 266: 8b 95 dc fd ff ff mov -0x224(%ebp),%edx + 26c: 57 push %edi + 26d: 0f bf 85 d4 fd ff ff movswl -0x22c(%ebp),%eax + 274: 89 8d ac fd ff ff mov %ecx,-0x254(%ebp) + 27a: 89 95 b0 fd ff ff mov %edx,-0x250(%ebp) + 280: 89 85 b4 fd ff ff mov %eax,-0x24c(%ebp) + 286: e8 d5 fd ff ff call 60 + 28b: 5a pop %edx + 28c: 8b 95 b0 fd ff ff mov -0x250(%ebp),%edx + 292: 59 pop %ecx + 293: 8b 8d ac fd ff ff mov -0x254(%ebp),%ecx + 299: 51 push %ecx + 29a: 52 push %edx + 29b: ff b5 b4 fd ff ff push -0x24c(%ebp) + 2a1: 50 push %eax + 2a2: 68 50 0a 00 00 push $0xa50 + 2a7: 6a 01 push $0x1 + 2a9: e8 52 04 00 00 call 700 + 2ae: 83 c4 20 add $0x20,%esp + 2b1: e9 4a ff ff ff jmp 200 + 2b6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2bd: 8d 76 00 lea 0x0(%esi),%esi + printf(2, "ls: cannot open %s\n", path); + 2c0: 83 ec 04 sub $0x4,%esp + 2c3: 57 push %edi + 2c4: 68 28 0a 00 00 push $0xa28 + 2c9: 6a 02 push $0x2 + 2cb: e8 30 04 00 00 call 700 + return; + 2d0: 83 c4 10 add $0x10,%esp +} + 2d3: 8d 65 f4 lea -0xc(%ebp),%esp + 2d6: 5b pop %ebx + 2d7: 5e pop %esi + 2d8: 5f pop %edi + 2d9: 5d pop %ebp + 2da: c3 ret + 2db: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 2df: 90 nop + printf(1, "ls: path too long\n"); + 2e0: 83 ec 08 sub $0x8,%esp + 2e3: 68 5d 0a 00 00 push $0xa5d + 2e8: 6a 01 push $0x1 + 2ea: e8 11 04 00 00 call 700 + break; + 2ef: 83 c4 10 add $0x10,%esp + 2f2: e9 5b fe ff ff jmp 152 + 2f7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2fe: 66 90 xchg %ax,%ax + printf(2, "ls: cannot stat %s\n", path); + 300: 83 ec 04 sub $0x4,%esp + 303: 57 push %edi + 304: 68 3c 0a 00 00 push $0xa3c + 309: 6a 02 push $0x2 + 30b: e8 f0 03 00 00 call 700 + close(fd); + 310: 89 1c 24 mov %ebx,(%esp) + 313: e8 13 03 00 00 call 62b + return; + 318: 83 c4 10 add $0x10,%esp +} + 31b: 8d 65 f4 lea -0xc(%ebp),%esp + 31e: 5b pop %ebx + 31f: 5e pop %esi + 320: 5f pop %edi + 321: 5d pop %ebp + 322: c3 ret + 323: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 327: 90 nop + printf(1, "ls: cannot stat %s\n", buf); + 328: 83 ec 04 sub $0x4,%esp + 32b: 57 push %edi + 32c: 68 3c 0a 00 00 push $0xa3c + 331: 6a 01 push $0x1 + 333: e8 c8 03 00 00 call 700 + continue; + 338: 83 c4 10 add $0x10,%esp + 33b: e9 c0 fe ff ff jmp 200 + +00000340 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 340: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 341: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 343: 89 e5 mov %esp,%ebp + 345: 53 push %ebx + 346: 8b 4d 08 mov 0x8(%ebp),%ecx + 349: 8b 5d 0c mov 0xc(%ebp),%ebx + 34c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 350: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 354: 88 14 01 mov %dl,(%ecx,%eax,1) + 357: 83 c0 01 add $0x1,%eax + 35a: 84 d2 test %dl,%dl + 35c: 75 f2 jne 350 + ; + } + return os; +} + 35e: 8b 5d fc mov -0x4(%ebp),%ebx + 361: 89 c8 mov %ecx,%eax + 363: c9 leave + 364: c3 ret + 365: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 36c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000370 : + +int strcmp(const char *p, const char *q) { + 370: 55 push %ebp + 371: 89 e5 mov %esp,%ebp + 373: 53 push %ebx + 374: 8b 55 08 mov 0x8(%ebp),%edx + 377: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 37a: 0f b6 02 movzbl (%edx),%eax + 37d: 84 c0 test %al,%al + 37f: 75 17 jne 398 + 381: eb 3a jmp 3bd + 383: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 387: 90 nop + 388: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 38c: 83 c2 01 add $0x1,%edx + 38f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 392: 84 c0 test %al,%al + 394: 74 1a je 3b0 + p++, q++; + 396: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 398: 0f b6 19 movzbl (%ecx),%ebx + 39b: 38 c3 cmp %al,%bl + 39d: 74 e9 je 388 + } + return (uchar) * p - (uchar) * q; + 39f: 29 d8 sub %ebx,%eax +} + 3a1: 8b 5d fc mov -0x4(%ebp),%ebx + 3a4: c9 leave + 3a5: c3 ret + 3a6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3ad: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 3b0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 3b4: 31 c0 xor %eax,%eax + 3b6: 29 d8 sub %ebx,%eax +} + 3b8: 8b 5d fc mov -0x4(%ebp),%ebx + 3bb: c9 leave + 3bc: c3 ret + return (uchar) * p - (uchar) * q; + 3bd: 0f b6 19 movzbl (%ecx),%ebx + 3c0: 31 c0 xor %eax,%eax + 3c2: eb db jmp 39f + 3c4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3cb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 3cf: 90 nop + +000003d0 : + +uint strlen(const char *s) { + 3d0: 55 push %ebp + 3d1: 89 e5 mov %esp,%ebp + 3d3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 3d6: 80 3a 00 cmpb $0x0,(%edx) + 3d9: 74 15 je 3f0 + 3db: 31 c0 xor %eax,%eax + 3dd: 8d 76 00 lea 0x0(%esi),%esi + 3e0: 83 c0 01 add $0x1,%eax + 3e3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 3e7: 89 c1 mov %eax,%ecx + 3e9: 75 f5 jne 3e0 + ; + } + return n; +} + 3eb: 89 c8 mov %ecx,%eax + 3ed: 5d pop %ebp + 3ee: c3 ret + 3ef: 90 nop + for (n = 0; s[n]; n++) { + 3f0: 31 c9 xor %ecx,%ecx +} + 3f2: 5d pop %ebp + 3f3: 89 c8 mov %ecx,%eax + 3f5: c3 ret + 3f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3fd: 8d 76 00 lea 0x0(%esi),%esi + +00000400 : + +void* memset(void *dst, int c, uint n) { + 400: 55 push %ebp + 401: 89 e5 mov %esp,%ebp + 403: 57 push %edi + 404: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 407: 8b 4d 10 mov 0x10(%ebp),%ecx + 40a: 8b 45 0c mov 0xc(%ebp),%eax + 40d: 89 d7 mov %edx,%edi + 40f: fc cld + 410: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 412: 8b 7d fc mov -0x4(%ebp),%edi + 415: 89 d0 mov %edx,%eax + 417: c9 leave + 418: c3 ret + 419: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000420 : + +char* strchr(const char *s, char c) { + 420: 55 push %ebp + 421: 89 e5 mov %esp,%ebp + 423: 8b 45 08 mov 0x8(%ebp),%eax + 426: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 42a: 0f b6 10 movzbl (%eax),%edx + 42d: 84 d2 test %dl,%dl + 42f: 75 12 jne 443 + 431: eb 1d jmp 450 + 433: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 437: 90 nop + 438: 0f b6 50 01 movzbl 0x1(%eax),%edx + 43c: 83 c0 01 add $0x1,%eax + 43f: 84 d2 test %dl,%dl + 441: 74 0d je 450 + if (*s == c) { + 443: 38 d1 cmp %dl,%cl + 445: 75 f1 jne 438 + return (char*)s; + } + } + return 0; +} + 447: 5d pop %ebp + 448: c3 ret + 449: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 450: 31 c0 xor %eax,%eax +} + 452: 5d pop %ebp + 453: c3 ret + 454: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 45b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 45f: 90 nop + +00000460 : + +char* gets(char *buf, int max) { + 460: 55 push %ebp + 461: 89 e5 mov %esp,%ebp + 463: 57 push %edi + 464: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 465: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 468: 53 push %ebx + for (i = 0; i + 1 < max;) { + 469: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 46b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 46e: eb 27 jmp 497 + cc = read(0, &c, 1); + 470: 83 ec 04 sub $0x4,%esp + 473: 6a 01 push $0x1 + 475: 57 push %edi + 476: 6a 00 push $0x0 + 478: e8 2e 01 00 00 call 5ab + if (cc < 1) { + 47d: 83 c4 10 add $0x10,%esp + 480: 85 c0 test %eax,%eax + 482: 7e 1d jle 4a1 + break; + } + buf[i++] = c; + 484: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 488: 8b 55 08 mov 0x8(%ebp),%edx + 48b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 48f: 3c 0a cmp $0xa,%al + 491: 74 1d je 4b0 + 493: 3c 0d cmp $0xd,%al + 495: 74 19 je 4b0 + for (i = 0; i + 1 < max;) { + 497: 89 de mov %ebx,%esi + 499: 83 c3 01 add $0x1,%ebx + 49c: 3b 5d 0c cmp 0xc(%ebp),%ebx + 49f: 7c cf jl 470 + break; + } + } + buf[i] = '\0'; + 4a1: 8b 45 08 mov 0x8(%ebp),%eax + 4a4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 4a8: 8d 65 f4 lea -0xc(%ebp),%esp + 4ab: 5b pop %ebx + 4ac: 5e pop %esi + 4ad: 5f pop %edi + 4ae: 5d pop %ebp + 4af: c3 ret + buf[i] = '\0'; + 4b0: 8b 45 08 mov 0x8(%ebp),%eax + 4b3: 89 de mov %ebx,%esi + 4b5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 4b9: 8d 65 f4 lea -0xc(%ebp),%esp + 4bc: 5b pop %ebx + 4bd: 5e pop %esi + 4be: 5f pop %edi + 4bf: 5d pop %ebp + 4c0: c3 ret + 4c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4cf: 90 nop + +000004d0 : + +int stat(const char *n, struct stat *st) { + 4d0: 55 push %ebp + 4d1: 89 e5 mov %esp,%ebp + 4d3: 56 push %esi + 4d4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 4d5: 83 ec 08 sub $0x8,%esp + 4d8: 6a 00 push $0x0 + 4da: ff 75 08 push 0x8(%ebp) + 4dd: e8 19 01 00 00 call 5fb + if (fd < 0) { + 4e2: 83 c4 10 add $0x10,%esp + 4e5: 85 c0 test %eax,%eax + 4e7: 78 27 js 510 + return -1; + } + r = fstat(fd, st); + 4e9: 83 ec 08 sub $0x8,%esp + 4ec: ff 75 0c push 0xc(%ebp) + 4ef: 89 c3 mov %eax,%ebx + 4f1: 50 push %eax + 4f2: e8 cc 00 00 00 call 5c3 + close(fd); + 4f7: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 4fa: 89 c6 mov %eax,%esi + close(fd); + 4fc: e8 2a 01 00 00 call 62b + return r; + 501: 83 c4 10 add $0x10,%esp +} + 504: 8d 65 f8 lea -0x8(%ebp),%esp + 507: 89 f0 mov %esi,%eax + 509: 5b pop %ebx + 50a: 5e pop %esi + 50b: 5d pop %ebp + 50c: c3 ret + 50d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 510: be ff ff ff ff mov $0xffffffff,%esi + 515: eb ed jmp 504 + 517: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 51e: 66 90 xchg %ax,%ax + +00000520 : + +int atoi(const char *s) { + 520: 55 push %ebp + 521: 89 e5 mov %esp,%ebp + 523: 53 push %ebx + 524: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 527: 0f be 02 movsbl (%edx),%eax + 52a: 8d 48 d0 lea -0x30(%eax),%ecx + 52d: 80 f9 09 cmp $0x9,%cl + n = 0; + 530: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 535: 77 1e ja 555 + 537: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 53e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 540: 83 c2 01 add $0x1,%edx + 543: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 546: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 54a: 0f be 02 movsbl (%edx),%eax + 54d: 8d 58 d0 lea -0x30(%eax),%ebx + 550: 80 fb 09 cmp $0x9,%bl + 553: 76 eb jbe 540 + } + return n; +} + 555: 8b 5d fc mov -0x4(%ebp),%ebx + 558: 89 c8 mov %ecx,%eax + 55a: c9 leave + 55b: c3 ret + 55c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000560 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 560: 55 push %ebp + 561: 89 e5 mov %esp,%ebp + 563: 57 push %edi + 564: 8b 45 10 mov 0x10(%ebp),%eax + 567: 8b 55 08 mov 0x8(%ebp),%edx + 56a: 56 push %esi + 56b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 56e: 85 c0 test %eax,%eax + 570: 7e 13 jle 585 + 572: 01 d0 add %edx,%eax + dst = vdst; + 574: 89 d7 mov %edx,%edi + 576: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 57d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 580: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 581: 39 f8 cmp %edi,%eax + 583: 75 fb jne 580 + } + return vdst; +} + 585: 5e pop %esi + 586: 89 d0 mov %edx,%eax + 588: 5f pop %edi + 589: 5d pop %ebp + 58a: c3 ret + +0000058b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 58b: b8 01 00 00 00 mov $0x1,%eax + 590: cd 40 int $0x40 + 592: c3 ret + +00000593 : +SYSCALL(exit) + 593: b8 02 00 00 00 mov $0x2,%eax + 598: cd 40 int $0x40 + 59a: c3 ret + +0000059b : +SYSCALL(wait) + 59b: b8 03 00 00 00 mov $0x3,%eax + 5a0: cd 40 int $0x40 + 5a2: c3 ret + +000005a3 : +SYSCALL(pipe) + 5a3: b8 04 00 00 00 mov $0x4,%eax + 5a8: cd 40 int $0x40 + 5aa: c3 ret + +000005ab : +SYSCALL(read) + 5ab: b8 05 00 00 00 mov $0x5,%eax + 5b0: cd 40 int $0x40 + 5b2: c3 ret + +000005b3 : +SYSCALL(kill) + 5b3: b8 06 00 00 00 mov $0x6,%eax + 5b8: cd 40 int $0x40 + 5ba: c3 ret + +000005bb : +SYSCALL(exec) + 5bb: b8 07 00 00 00 mov $0x7,%eax + 5c0: cd 40 int $0x40 + 5c2: c3 ret + +000005c3 : +SYSCALL(fstat) + 5c3: b8 08 00 00 00 mov $0x8,%eax + 5c8: cd 40 int $0x40 + 5ca: c3 ret + +000005cb : +SYSCALL(chdir) + 5cb: b8 09 00 00 00 mov $0x9,%eax + 5d0: cd 40 int $0x40 + 5d2: c3 ret + +000005d3 : +SYSCALL(dup) + 5d3: b8 0a 00 00 00 mov $0xa,%eax + 5d8: cd 40 int $0x40 + 5da: c3 ret + +000005db : +SYSCALL(getpid) + 5db: b8 0b 00 00 00 mov $0xb,%eax + 5e0: cd 40 int $0x40 + 5e2: c3 ret + +000005e3 : +SYSCALL(sbrk) + 5e3: b8 0c 00 00 00 mov $0xc,%eax + 5e8: cd 40 int $0x40 + 5ea: c3 ret + +000005eb : +SYSCALL(sleep) + 5eb: b8 0d 00 00 00 mov $0xd,%eax + 5f0: cd 40 int $0x40 + 5f2: c3 ret + +000005f3 : +SYSCALL(uptime) + 5f3: b8 0e 00 00 00 mov $0xe,%eax + 5f8: cd 40 int $0x40 + 5fa: c3 ret + +000005fb : +SYSCALL(open) + 5fb: b8 0f 00 00 00 mov $0xf,%eax + 600: cd 40 int $0x40 + 602: c3 ret + +00000603 : +SYSCALL(write) + 603: b8 10 00 00 00 mov $0x10,%eax + 608: cd 40 int $0x40 + 60a: c3 ret + +0000060b : +SYSCALL(mknod) + 60b: b8 11 00 00 00 mov $0x11,%eax + 610: cd 40 int $0x40 + 612: c3 ret + +00000613 : +SYSCALL(unlink) + 613: b8 12 00 00 00 mov $0x12,%eax + 618: cd 40 int $0x40 + 61a: c3 ret + +0000061b : +SYSCALL(link) + 61b: b8 13 00 00 00 mov $0x13,%eax + 620: cd 40 int $0x40 + 622: c3 ret + +00000623 : +SYSCALL(mkdir) + 623: b8 14 00 00 00 mov $0x14,%eax + 628: cd 40 int $0x40 + 62a: c3 ret + +0000062b : +SYSCALL(close) + 62b: b8 15 00 00 00 mov $0x15,%eax + 630: cd 40 int $0x40 + 632: c3 ret + +00000633 : +SYSCALL(getch) + 633: b8 16 00 00 00 mov $0x16,%eax + 638: cd 40 int $0x40 + 63a: c3 ret + +0000063b : +SYSCALL(greeting) + 63b: b8 17 00 00 00 mov $0x17,%eax + 640: cd 40 int $0x40 + 642: c3 ret + +00000643 : +SYSCALL(shutdown) + 643: b8 18 00 00 00 mov $0x18,%eax + 648: cd 40 int $0x40 + 64a: c3 ret + 64b: 66 90 xchg %ax,%ax + 64d: 66 90 xchg %ax,%ax + 64f: 90 nop + +00000650 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 650: 55 push %ebp + 651: 89 e5 mov %esp,%ebp + 653: 57 push %edi + 654: 56 push %esi + 655: 53 push %ebx + 656: 83 ec 3c sub $0x3c,%esp + 659: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 65c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 65e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 661: 85 d2 test %edx,%edx + 663: 0f 89 7f 00 00 00 jns 6e8 + 669: f6 45 08 01 testb $0x1,0x8(%ebp) + 66d: 74 79 je 6e8 + neg = 1; + 66f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 676: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 678: 31 db xor %ebx,%ebx + 67a: 8d 75 d7 lea -0x29(%ebp),%esi + 67d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 680: 89 c8 mov %ecx,%eax + 682: 31 d2 xor %edx,%edx + 684: 89 cf mov %ecx,%edi + 686: f7 75 c4 divl -0x3c(%ebp) + 689: 0f b6 92 d4 0a 00 00 movzbl 0xad4(%edx),%edx + 690: 89 45 c0 mov %eax,-0x40(%ebp) + 693: 89 d8 mov %ebx,%eax + 695: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 698: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 69b: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 69e: 39 7d c4 cmp %edi,-0x3c(%ebp) + 6a1: 76 dd jbe 680 + if (neg) { + 6a3: 8b 4d bc mov -0x44(%ebp),%ecx + 6a6: 85 c9 test %ecx,%ecx + 6a8: 74 0c je 6b6 + buf[i++] = '-'; + 6aa: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 6af: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 6b1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 6b6: 8b 7d b8 mov -0x48(%ebp),%edi + 6b9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 6bd: eb 07 jmp 6c6 + 6bf: 90 nop + putc(fd, buf[i]); + 6c0: 0f b6 13 movzbl (%ebx),%edx + 6c3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 6c6: 83 ec 04 sub $0x4,%esp + 6c9: 88 55 d7 mov %dl,-0x29(%ebp) + 6cc: 6a 01 push $0x1 + 6ce: 56 push %esi + 6cf: 57 push %edi + 6d0: e8 2e ff ff ff call 603 + while (--i >= 0) { + 6d5: 83 c4 10 add $0x10,%esp + 6d8: 39 de cmp %ebx,%esi + 6da: 75 e4 jne 6c0 + } +} + 6dc: 8d 65 f4 lea -0xc(%ebp),%esp + 6df: 5b pop %ebx + 6e0: 5e pop %esi + 6e1: 5f pop %edi + 6e2: 5d pop %ebp + 6e3: c3 ret + 6e4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 6e8: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 6ef: eb 87 jmp 678 + 6f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 6f8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 6ff: 90 nop + +00000700 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 700: 55 push %ebp + 701: 89 e5 mov %esp,%ebp + 703: 57 push %edi + 704: 56 push %esi + 705: 53 push %ebx + 706: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 709: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 70c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 70f: 0f b6 13 movzbl (%ebx),%edx + 712: 84 d2 test %dl,%dl + 714: 74 6a je 780 + ap = (uint*)(void*)&fmt + 1; + 716: 8d 45 10 lea 0x10(%ebp),%eax + 719: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 71c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 71f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 721: 89 45 d0 mov %eax,-0x30(%ebp) + 724: eb 36 jmp 75c + 726: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 72d: 8d 76 00 lea 0x0(%esi),%esi + 730: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 733: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 738: 83 f8 25 cmp $0x25,%eax + 73b: 74 15 je 752 + write(fd, &c, 1); + 73d: 83 ec 04 sub $0x4,%esp + 740: 88 55 e7 mov %dl,-0x19(%ebp) + 743: 6a 01 push $0x1 + 745: 57 push %edi + 746: 56 push %esi + 747: e8 b7 fe ff ff call 603 + 74c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 74f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 752: 0f b6 13 movzbl (%ebx),%edx + 755: 83 c3 01 add $0x1,%ebx + 758: 84 d2 test %dl,%dl + 75a: 74 24 je 780 + c = fmt[i] & 0xff; + 75c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 75f: 85 c9 test %ecx,%ecx + 761: 74 cd je 730 + } + } + else if (state == '%') { + 763: 83 f9 25 cmp $0x25,%ecx + 766: 75 ea jne 752 + if (c == 'd') { + 768: 83 f8 25 cmp $0x25,%eax + 76b: 0f 84 07 01 00 00 je 878 + 771: 83 e8 63 sub $0x63,%eax + 774: 83 f8 15 cmp $0x15,%eax + 777: 77 17 ja 790 + 779: ff 24 85 7c 0a 00 00 jmp *0xa7c(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 780: 8d 65 f4 lea -0xc(%ebp),%esp + 783: 5b pop %ebx + 784: 5e pop %esi + 785: 5f pop %edi + 786: 5d pop %ebp + 787: c3 ret + 788: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 78f: 90 nop + write(fd, &c, 1); + 790: 83 ec 04 sub $0x4,%esp + 793: 88 55 d4 mov %dl,-0x2c(%ebp) + 796: 6a 01 push $0x1 + 798: 57 push %edi + 799: 56 push %esi + 79a: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 79e: e8 60 fe ff ff call 603 + putc(fd, c); + 7a3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 7a7: 83 c4 0c add $0xc,%esp + 7aa: 88 55 e7 mov %dl,-0x19(%ebp) + 7ad: 6a 01 push $0x1 + 7af: 57 push %edi + 7b0: 56 push %esi + 7b1: e8 4d fe ff ff call 603 + putc(fd, c); + 7b6: 83 c4 10 add $0x10,%esp + state = 0; + 7b9: 31 c9 xor %ecx,%ecx + 7bb: eb 95 jmp 752 + 7bd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 7c0: 83 ec 0c sub $0xc,%esp + 7c3: b9 10 00 00 00 mov $0x10,%ecx + 7c8: 6a 00 push $0x0 + 7ca: 8b 45 d0 mov -0x30(%ebp),%eax + 7cd: 8b 10 mov (%eax),%edx + 7cf: 89 f0 mov %esi,%eax + 7d1: e8 7a fe ff ff call 650 + ap++; + 7d6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 7da: 83 c4 10 add $0x10,%esp + state = 0; + 7dd: 31 c9 xor %ecx,%ecx + 7df: e9 6e ff ff ff jmp 752 + 7e4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 7e8: 8b 45 d0 mov -0x30(%ebp),%eax + 7eb: 8b 10 mov (%eax),%edx + ap++; + 7ed: 83 c0 04 add $0x4,%eax + 7f0: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 7f3: 85 d2 test %edx,%edx + 7f5: 0f 84 8d 00 00 00 je 888 + while (*s != 0) { + 7fb: 0f b6 02 movzbl (%edx),%eax + state = 0; + 7fe: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 800: 84 c0 test %al,%al + 802: 0f 84 4a ff ff ff je 752 + 808: 89 5d d4 mov %ebx,-0x2c(%ebp) + 80b: 89 d3 mov %edx,%ebx + 80d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 810: 83 ec 04 sub $0x4,%esp + s++; + 813: 83 c3 01 add $0x1,%ebx + 816: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 819: 6a 01 push $0x1 + 81b: 57 push %edi + 81c: 56 push %esi + 81d: e8 e1 fd ff ff call 603 + while (*s != 0) { + 822: 0f b6 03 movzbl (%ebx),%eax + 825: 83 c4 10 add $0x10,%esp + 828: 84 c0 test %al,%al + 82a: 75 e4 jne 810 + state = 0; + 82c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 82f: 31 c9 xor %ecx,%ecx + 831: e9 1c ff ff ff jmp 752 + 836: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 83d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 840: 83 ec 0c sub $0xc,%esp + 843: b9 0a 00 00 00 mov $0xa,%ecx + 848: 6a 01 push $0x1 + 84a: e9 7b ff ff ff jmp 7ca + 84f: 90 nop + putc(fd, *ap); + 850: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 853: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 856: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 858: 6a 01 push $0x1 + 85a: 57 push %edi + 85b: 56 push %esi + putc(fd, *ap); + 85c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 85f: e8 9f fd ff ff call 603 + ap++; + 864: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 868: 83 c4 10 add $0x10,%esp + state = 0; + 86b: 31 c9 xor %ecx,%ecx + 86d: e9 e0 fe ff ff jmp 752 + 872: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 878: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 87b: 83 ec 04 sub $0x4,%esp + 87e: e9 2a ff ff ff jmp 7ad + 883: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 887: 90 nop + s = "(null)"; + 888: ba 72 0a 00 00 mov $0xa72,%edx + while (*s != 0) { + 88d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 890: b8 28 00 00 00 mov $0x28,%eax + 895: 89 d3 mov %edx,%ebx + 897: e9 74 ff ff ff jmp 810 + 89c: 66 90 xchg %ax,%ax + 89e: 66 90 xchg %ax,%ax + +000008a0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 8a0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 8a1: a1 14 0e 00 00 mov 0xe14,%eax +void free(void *ap) { + 8a6: 89 e5 mov %esp,%ebp + 8a8: 57 push %edi + 8a9: 56 push %esi + 8aa: 53 push %ebx + 8ab: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 8ae: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 8b1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 8b8: 89 c2 mov %eax,%edx + 8ba: 8b 00 mov (%eax),%eax + 8bc: 39 ca cmp %ecx,%edx + 8be: 73 30 jae 8f0 + 8c0: 39 c1 cmp %eax,%ecx + 8c2: 72 04 jb 8c8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 8c4: 39 c2 cmp %eax,%edx + 8c6: 72 f0 jb 8b8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 8c8: 8b 73 fc mov -0x4(%ebx),%esi + 8cb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 8ce: 39 f8 cmp %edi,%eax + 8d0: 74 30 je 902 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 8d2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 8d5: 8b 42 04 mov 0x4(%edx),%eax + 8d8: 8d 34 c2 lea (%edx,%eax,8),%esi + 8db: 39 f1 cmp %esi,%ecx + 8dd: 74 3a je 919 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 8df: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 8e1: 5b pop %ebx + freep = p; + 8e2: 89 15 14 0e 00 00 mov %edx,0xe14 +} + 8e8: 5e pop %esi + 8e9: 5f pop %edi + 8ea: 5d pop %ebp + 8eb: c3 ret + 8ec: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 8f0: 39 c2 cmp %eax,%edx + 8f2: 72 c4 jb 8b8 + 8f4: 39 c1 cmp %eax,%ecx + 8f6: 73 c0 jae 8b8 + if (bp + bp->s.size == p->s.ptr) { + 8f8: 8b 73 fc mov -0x4(%ebx),%esi + 8fb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 8fe: 39 f8 cmp %edi,%eax + 900: 75 d0 jne 8d2 + bp->s.size += p->s.ptr->s.size; + 902: 03 70 04 add 0x4(%eax),%esi + 905: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 908: 8b 02 mov (%edx),%eax + 90a: 8b 00 mov (%eax),%eax + 90c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 90f: 8b 42 04 mov 0x4(%edx),%eax + 912: 8d 34 c2 lea (%edx,%eax,8),%esi + 915: 39 f1 cmp %esi,%ecx + 917: 75 c6 jne 8df + p->s.size += bp->s.size; + 919: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 91c: 89 15 14 0e 00 00 mov %edx,0xe14 + p->s.size += bp->s.size; + 922: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 925: 8b 4b f8 mov -0x8(%ebx),%ecx + 928: 89 0a mov %ecx,(%edx) +} + 92a: 5b pop %ebx + 92b: 5e pop %esi + 92c: 5f pop %edi + 92d: 5d pop %ebp + 92e: c3 ret + 92f: 90 nop + +00000930 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 930: 55 push %ebp + 931: 89 e5 mov %esp,%ebp + 933: 57 push %edi + 934: 56 push %esi + 935: 53 push %ebx + 936: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 939: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 93c: 8b 3d 14 0e 00 00 mov 0xe14,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 942: 8d 70 07 lea 0x7(%eax),%esi + 945: c1 ee 03 shr $0x3,%esi + 948: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 94b: 85 ff test %edi,%edi + 94d: 0f 84 9d 00 00 00 je 9f0 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 953: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 955: 8b 4a 04 mov 0x4(%edx),%ecx + 958: 39 f1 cmp %esi,%ecx + 95a: 73 6a jae 9c6 + 95c: bb 00 10 00 00 mov $0x1000,%ebx + 961: 39 de cmp %ebx,%esi + 963: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 966: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 96d: 89 45 e4 mov %eax,-0x1c(%ebp) + 970: eb 17 jmp 989 + 972: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 978: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 97a: 8b 48 04 mov 0x4(%eax),%ecx + 97d: 39 f1 cmp %esi,%ecx + 97f: 73 4f jae 9d0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 981: 8b 3d 14 0e 00 00 mov 0xe14,%edi + 987: 89 c2 mov %eax,%edx + 989: 39 d7 cmp %edx,%edi + 98b: 75 eb jne 978 + p = sbrk(nu * sizeof(Header)); + 98d: 83 ec 0c sub $0xc,%esp + 990: ff 75 e4 push -0x1c(%ebp) + 993: e8 4b fc ff ff call 5e3 + if (p == (char*)-1) { + 998: 83 c4 10 add $0x10,%esp + 99b: 83 f8 ff cmp $0xffffffff,%eax + 99e: 74 1c je 9bc + hp->s.size = nu; + 9a0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 9a3: 83 ec 0c sub $0xc,%esp + 9a6: 83 c0 08 add $0x8,%eax + 9a9: 50 push %eax + 9aa: e8 f1 fe ff ff call 8a0 + return freep; + 9af: 8b 15 14 0e 00 00 mov 0xe14,%edx + if ((p = morecore(nunits)) == 0) { + 9b5: 83 c4 10 add $0x10,%esp + 9b8: 85 d2 test %edx,%edx + 9ba: 75 bc jne 978 + return 0; + } + } + } +} + 9bc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 9bf: 31 c0 xor %eax,%eax +} + 9c1: 5b pop %ebx + 9c2: 5e pop %esi + 9c3: 5f pop %edi + 9c4: 5d pop %ebp + 9c5: c3 ret + if (p->s.size >= nunits) { + 9c6: 89 d0 mov %edx,%eax + 9c8: 89 fa mov %edi,%edx + 9ca: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 9d0: 39 ce cmp %ecx,%esi + 9d2: 74 4c je a20 + p->s.size -= nunits; + 9d4: 29 f1 sub %esi,%ecx + 9d6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 9d9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 9dc: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 9df: 89 15 14 0e 00 00 mov %edx,0xe14 +} + 9e5: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 9e8: 83 c0 08 add $0x8,%eax +} + 9eb: 5b pop %ebx + 9ec: 5e pop %esi + 9ed: 5f pop %edi + 9ee: 5d pop %ebp + 9ef: c3 ret + base.s.ptr = freep = prevp = &base; + 9f0: c7 05 14 0e 00 00 18 movl $0xe18,0xe14 + 9f7: 0e 00 00 + base.s.size = 0; + 9fa: bf 18 0e 00 00 mov $0xe18,%edi + base.s.ptr = freep = prevp = &base; + 9ff: c7 05 18 0e 00 00 18 movl $0xe18,0xe18 + a06: 0e 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + a09: 89 fa mov %edi,%edx + base.s.size = 0; + a0b: c7 05 1c 0e 00 00 00 movl $0x0,0xe1c + a12: 00 00 00 + if (p->s.size >= nunits) { + a15: e9 42 ff ff ff jmp 95c + a1a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + a20: 8b 08 mov (%eax),%ecx + a22: 89 0a mov %ecx,(%edx) + a24: eb b9 jmp 9df diff --git a/ls.c b/ls.c new file mode 100644 index 0000000..2862913 --- /dev/null +++ b/ls.c @@ -0,0 +1,85 @@ +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fs.h" + +char* +fmtname(char *path) +{ + static char buf[DIRSIZ+1]; + char *p; + + // Find first character after last slash. + for(p=path+strlen(path); p >= path && *p != '/'; p--) + ; + p++; + + // Return blank-padded name. + if(strlen(p) >= DIRSIZ) + return p; + memmove(buf, p, strlen(p)); + memset(buf+strlen(p), ' ', DIRSIZ-strlen(p)); + return buf; +} + +void +ls(char *path) +{ + char buf[512], *p; + int fd; + struct dirent de; + struct stat st; + + if((fd = open(path, 0)) < 0){ + printf(2, "ls: cannot open %s\n", path); + return; + } + + if(fstat(fd, &st) < 0){ + printf(2, "ls: cannot stat %s\n", path); + close(fd); + return; + } + + switch(st.type){ + case T_FILE: + printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size); + break; + + case T_DIR: + if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ + printf(1, "ls: path too long\n"); + break; + } + strcpy(buf, path); + p = buf+strlen(buf); + *p++ = '/'; + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + if(de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = 0; + if(stat(buf, &st) < 0){ + printf(1, "ls: cannot stat %s\n", buf); + continue; + } + printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size); + } + break; + } + close(fd); +} + +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + ls("."); + exit(); + } + for(i=1; istarted), 1); // tell startothers() we're up + scheduler(); // start running processes +} + +pde_t entrypgdir[]; // For entry.S + +// Start the non-boot (AP) processors. +static void startothers(void) { + extern uchar _binary_entryother_start[], _binary_entryother_size[]; + uchar *code; + struct cpu *c; + char *stack; + + // Write entry code to unused memory at 0x7000. + // The linker has placed the image of entryother.S in + // _binary_entryother_start. + code = P2V(0x7000); + memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); + + for (c = cpus; c < cpus + ncpu; c++) { + if (c == mycpu()) { // We've started already. + continue; + } + + // Tell entryother.S what stack to use, where to enter, and what + // pgdir to use. We cannot use kpgdir yet, because the AP processor + // is running in low memory, so we use entrypgdir for the APs too. + stack = kalloc(); + *(void**)(code - 4) = stack + KSTACKSIZE; + *(void(**)(void))(code - 8) = mpenter; + *(int**)(code - 12) = (void *) V2P(entrypgdir); + + lapicstartap(c->apicid, V2P(code)); + + // wait for cpu to finish mpmain() + while (c->started == 0) { + ; + } + } +} + +// The boot page table used in entry.S and entryother.S. +// Page directories (and page tables) must start on page boundaries, +// hence the __aligned__ attribute. +// PTE_PS in a page directory entry enables 4Mbyte pages. + +__attribute__((__aligned__(PGSIZE))) +pde_t entrypgdir[NPDENTRIES] = { + // Map VA's [0, 4MB) to PA's [0, 4MB) + [0] = (0) | PTE_P | PTE_W | PTE_PS, + // Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB) + [KERNBASE >> PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS, +}; + + + + + + + + diff --git a/main.d b/main.d new file mode 100644 index 0000000..354dab4 --- /dev/null +++ b/main.d @@ -0,0 +1,2 @@ +main.o: main.c /usr/include/stdc-predef.h types.h defs.h param.h \ + memlayout.h mmu.h proc.h x86.h diff --git a/main.o b/main.o new file mode 100644 index 0000000..3bd87b9 Binary files /dev/null and b/main.o differ diff --git a/memide.c b/memide.c new file mode 100644 index 0000000..d0a8cf8 --- /dev/null +++ b/memide.c @@ -0,0 +1,60 @@ +// Fake IDE disk; stores blocks in memory. +// Useful for running kernel without scratch disk. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "mmu.h" +#include "proc.h" +#include "x86.h" +#include "traps.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "fs.h" +#include "buf.h" + +extern uchar _binary_fs_img_start[], _binary_fs_img_size[]; + +static int disksize; +static uchar *memdisk; + +void ideinit(void) { + memdisk = _binary_fs_img_start; + disksize = (uint)_binary_fs_img_size / BSIZE; +} + +// Interrupt handler. +void ideintr(void) { + // no-op +} + +// Sync buf with disk. +// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID. +// Else if B_VALID is not set, read buf from disk, set B_VALID. +void iderw(struct buf *b) { + uchar *p; + + if (!holdingsleep(&b->lock)) { + panic("iderw: buf not locked"); + } + if ((b->flags & (B_VALID | B_DIRTY)) == B_VALID) { + panic("iderw: nothing to do"); + } + if (b->dev != 1) { + panic("iderw: request not for disk 1"); + } + if (b->blockno >= disksize) { + panic("iderw: block out of range"); + } + + p = memdisk + b->blockno * BSIZE; + + if (b->flags & B_DIRTY) { + b->flags &= ~B_DIRTY; + memmove(p, b->data, BSIZE); + } + else { + memmove(b->data, p, BSIZE); + } + b->flags |= B_VALID; +} diff --git a/memlayout.h b/memlayout.h new file mode 100644 index 0000000..8942340 --- /dev/null +++ b/memlayout.h @@ -0,0 +1,15 @@ +// Memory layout + +#define EXTMEM 0x100000 // Start of extended memory +#define PHYSTOP 0xE000000 // Top physical memory +#define DEVSPACE 0xFE000000 // Other devices are at high addresses + +// Key addresses for address space layout (see kmap in vm.c for layout) +#define KERNBASE 0x80000000 // First kernel virtual address +#define KERNLINK (KERNBASE + EXTMEM) // Address where kernel is linked + +#define V2P(a) (((uint) (a)) - KERNBASE) +#define P2V(a) ((void *)(((char *) (a)) + KERNBASE)) + +#define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts +#define P2V_WO(x) ((x) + KERNBASE) // same as P2V, but without casts diff --git a/mkdir.asm b/mkdir.asm new file mode 100644 index 0000000..ec2314a --- /dev/null +++ b/mkdir.asm @@ -0,0 +1,1190 @@ + +_mkdir: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: bf 01 00 00 00 mov $0x1,%edi + 13: 56 push %esi + 14: 53 push %ebx + 15: 51 push %ecx + 16: 83 ec 08 sub $0x8,%esp + 19: 8b 59 04 mov 0x4(%ecx),%ebx + 1c: 8b 31 mov (%ecx),%esi + 1e: 83 c3 04 add $0x4,%ebx + int i; + + if (argc < 2) { + 21: 83 fe 01 cmp $0x1,%esi + 24: 7e 3e jle 64 + 26: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2d: 8d 76 00 lea 0x0(%esi),%esi + printf(2, "Usage: mkdir files...\n"); + exit(); + } + + for (i = 1; i < argc; i++) { + if (mkdir(argv[i]) < 0) { + 30: 83 ec 0c sub $0xc,%esp + 33: ff 33 push (%ebx) + 35: e8 29 03 00 00 call 363 + 3a: 83 c4 10 add $0x10,%esp + 3d: 85 c0 test %eax,%eax + 3f: 78 0f js 50 + for (i = 1; i < argc; i++) { + 41: 83 c7 01 add $0x1,%edi + 44: 83 c3 04 add $0x4,%ebx + 47: 39 fe cmp %edi,%esi + 49: 75 e5 jne 30 + printf(2, "mkdir: %s failed to create\n", argv[i]); + break; + } + } + + exit(); + 4b: e8 83 02 00 00 call 2d3 + printf(2, "mkdir: %s failed to create\n", argv[i]); + 50: 50 push %eax + 51: ff 33 push (%ebx) + 53: 68 7f 07 00 00 push $0x77f + 58: 6a 02 push $0x2 + 5a: e8 e1 03 00 00 call 440 + break; + 5f: 83 c4 10 add $0x10,%esp + 62: eb e7 jmp 4b + printf(2, "Usage: mkdir files...\n"); + 64: 52 push %edx + 65: 52 push %edx + 66: 68 68 07 00 00 push $0x768 + 6b: 6a 02 push $0x2 + 6d: e8 ce 03 00 00 call 440 + exit(); + 72: e8 5c 02 00 00 call 2d3 + 77: 66 90 xchg %ax,%ax + 79: 66 90 xchg %ax,%ax + 7b: 66 90 xchg %ax,%ax + 7d: 66 90 xchg %ax,%ax + 7f: 90 nop + +00000080 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 80: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 81: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 83: 89 e5 mov %esp,%ebp + 85: 53 push %ebx + 86: 8b 4d 08 mov 0x8(%ebp),%ecx + 89: 8b 5d 0c mov 0xc(%ebp),%ebx + 8c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 90: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 94: 88 14 01 mov %dl,(%ecx,%eax,1) + 97: 83 c0 01 add $0x1,%eax + 9a: 84 d2 test %dl,%dl + 9c: 75 f2 jne 90 + ; + } + return os; +} + 9e: 8b 5d fc mov -0x4(%ebp),%ebx + a1: 89 c8 mov %ecx,%eax + a3: c9 leave + a4: c3 ret + a5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000000b0 : + +int strcmp(const char *p, const char *q) { + b0: 55 push %ebp + b1: 89 e5 mov %esp,%ebp + b3: 53 push %ebx + b4: 8b 55 08 mov 0x8(%ebp),%edx + b7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + ba: 0f b6 02 movzbl (%edx),%eax + bd: 84 c0 test %al,%al + bf: 75 17 jne d8 + c1: eb 3a jmp fd + c3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + c7: 90 nop + c8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + cc: 83 c2 01 add $0x1,%edx + cf: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + d2: 84 c0 test %al,%al + d4: 74 1a je f0 + p++, q++; + d6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + d8: 0f b6 19 movzbl (%ecx),%ebx + db: 38 c3 cmp %al,%bl + dd: 74 e9 je c8 + } + return (uchar) * p - (uchar) * q; + df: 29 d8 sub %ebx,%eax +} + e1: 8b 5d fc mov -0x4(%ebp),%ebx + e4: c9 leave + e5: c3 ret + e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + ed: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + f0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + f4: 31 c0 xor %eax,%eax + f6: 29 d8 sub %ebx,%eax +} + f8: 8b 5d fc mov -0x4(%ebp),%ebx + fb: c9 leave + fc: c3 ret + return (uchar) * p - (uchar) * q; + fd: 0f b6 19 movzbl (%ecx),%ebx + 100: 31 c0 xor %eax,%eax + 102: eb db jmp df + 104: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 10b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 10f: 90 nop + +00000110 : + +uint strlen(const char *s) { + 110: 55 push %ebp + 111: 89 e5 mov %esp,%ebp + 113: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 116: 80 3a 00 cmpb $0x0,(%edx) + 119: 74 15 je 130 + 11b: 31 c0 xor %eax,%eax + 11d: 8d 76 00 lea 0x0(%esi),%esi + 120: 83 c0 01 add $0x1,%eax + 123: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 127: 89 c1 mov %eax,%ecx + 129: 75 f5 jne 120 + ; + } + return n; +} + 12b: 89 c8 mov %ecx,%eax + 12d: 5d pop %ebp + 12e: c3 ret + 12f: 90 nop + for (n = 0; s[n]; n++) { + 130: 31 c9 xor %ecx,%ecx +} + 132: 5d pop %ebp + 133: 89 c8 mov %ecx,%eax + 135: c3 ret + 136: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 13d: 8d 76 00 lea 0x0(%esi),%esi + +00000140 : + +void* memset(void *dst, int c, uint n) { + 140: 55 push %ebp + 141: 89 e5 mov %esp,%ebp + 143: 57 push %edi + 144: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 147: 8b 4d 10 mov 0x10(%ebp),%ecx + 14a: 8b 45 0c mov 0xc(%ebp),%eax + 14d: 89 d7 mov %edx,%edi + 14f: fc cld + 150: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 152: 8b 7d fc mov -0x4(%ebp),%edi + 155: 89 d0 mov %edx,%eax + 157: c9 leave + 158: c3 ret + 159: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000160 : + +char* strchr(const char *s, char c) { + 160: 55 push %ebp + 161: 89 e5 mov %esp,%ebp + 163: 8b 45 08 mov 0x8(%ebp),%eax + 166: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 16a: 0f b6 10 movzbl (%eax),%edx + 16d: 84 d2 test %dl,%dl + 16f: 75 12 jne 183 + 171: eb 1d jmp 190 + 173: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 177: 90 nop + 178: 0f b6 50 01 movzbl 0x1(%eax),%edx + 17c: 83 c0 01 add $0x1,%eax + 17f: 84 d2 test %dl,%dl + 181: 74 0d je 190 + if (*s == c) { + 183: 38 d1 cmp %dl,%cl + 185: 75 f1 jne 178 + return (char*)s; + } + } + return 0; +} + 187: 5d pop %ebp + 188: c3 ret + 189: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 190: 31 c0 xor %eax,%eax +} + 192: 5d pop %ebp + 193: c3 ret + 194: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 19b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 19f: 90 nop + +000001a0 : + +char* gets(char *buf, int max) { + 1a0: 55 push %ebp + 1a1: 89 e5 mov %esp,%ebp + 1a3: 57 push %edi + 1a4: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 1a5: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 1a8: 53 push %ebx + for (i = 0; i + 1 < max;) { + 1a9: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 1ab: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 1ae: eb 27 jmp 1d7 + cc = read(0, &c, 1); + 1b0: 83 ec 04 sub $0x4,%esp + 1b3: 6a 01 push $0x1 + 1b5: 57 push %edi + 1b6: 6a 00 push $0x0 + 1b8: e8 2e 01 00 00 call 2eb + if (cc < 1) { + 1bd: 83 c4 10 add $0x10,%esp + 1c0: 85 c0 test %eax,%eax + 1c2: 7e 1d jle 1e1 + break; + } + buf[i++] = c; + 1c4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 1c8: 8b 55 08 mov 0x8(%ebp),%edx + 1cb: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 1cf: 3c 0a cmp $0xa,%al + 1d1: 74 1d je 1f0 + 1d3: 3c 0d cmp $0xd,%al + 1d5: 74 19 je 1f0 + for (i = 0; i + 1 < max;) { + 1d7: 89 de mov %ebx,%esi + 1d9: 83 c3 01 add $0x1,%ebx + 1dc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1df: 7c cf jl 1b0 + break; + } + } + buf[i] = '\0'; + 1e1: 8b 45 08 mov 0x8(%ebp),%eax + 1e4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1e8: 8d 65 f4 lea -0xc(%ebp),%esp + 1eb: 5b pop %ebx + 1ec: 5e pop %esi + 1ed: 5f pop %edi + 1ee: 5d pop %ebp + 1ef: c3 ret + buf[i] = '\0'; + 1f0: 8b 45 08 mov 0x8(%ebp),%eax + 1f3: 89 de mov %ebx,%esi + 1f5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 1f9: 8d 65 f4 lea -0xc(%ebp),%esp + 1fc: 5b pop %ebx + 1fd: 5e pop %esi + 1fe: 5f pop %edi + 1ff: 5d pop %ebp + 200: c3 ret + 201: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 208: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 20f: 90 nop + +00000210 : + +int stat(const char *n, struct stat *st) { + 210: 55 push %ebp + 211: 89 e5 mov %esp,%ebp + 213: 56 push %esi + 214: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 215: 83 ec 08 sub $0x8,%esp + 218: 6a 00 push $0x0 + 21a: ff 75 08 push 0x8(%ebp) + 21d: e8 19 01 00 00 call 33b + if (fd < 0) { + 222: 83 c4 10 add $0x10,%esp + 225: 85 c0 test %eax,%eax + 227: 78 27 js 250 + return -1; + } + r = fstat(fd, st); + 229: 83 ec 08 sub $0x8,%esp + 22c: ff 75 0c push 0xc(%ebp) + 22f: 89 c3 mov %eax,%ebx + 231: 50 push %eax + 232: e8 cc 00 00 00 call 303 + close(fd); + 237: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 23a: 89 c6 mov %eax,%esi + close(fd); + 23c: e8 2a 01 00 00 call 36b + return r; + 241: 83 c4 10 add $0x10,%esp +} + 244: 8d 65 f8 lea -0x8(%ebp),%esp + 247: 89 f0 mov %esi,%eax + 249: 5b pop %ebx + 24a: 5e pop %esi + 24b: 5d pop %ebp + 24c: c3 ret + 24d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 250: be ff ff ff ff mov $0xffffffff,%esi + 255: eb ed jmp 244 + 257: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 25e: 66 90 xchg %ax,%ax + +00000260 : + +int atoi(const char *s) { + 260: 55 push %ebp + 261: 89 e5 mov %esp,%ebp + 263: 53 push %ebx + 264: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 267: 0f be 02 movsbl (%edx),%eax + 26a: 8d 48 d0 lea -0x30(%eax),%ecx + 26d: 80 f9 09 cmp $0x9,%cl + n = 0; + 270: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 275: 77 1e ja 295 + 277: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 27e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 280: 83 c2 01 add $0x1,%edx + 283: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 286: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 28a: 0f be 02 movsbl (%edx),%eax + 28d: 8d 58 d0 lea -0x30(%eax),%ebx + 290: 80 fb 09 cmp $0x9,%bl + 293: 76 eb jbe 280 + } + return n; +} + 295: 8b 5d fc mov -0x4(%ebp),%ebx + 298: 89 c8 mov %ecx,%eax + 29a: c9 leave + 29b: c3 ret + 29c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000002a0 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 2a0: 55 push %ebp + 2a1: 89 e5 mov %esp,%ebp + 2a3: 57 push %edi + 2a4: 8b 45 10 mov 0x10(%ebp),%eax + 2a7: 8b 55 08 mov 0x8(%ebp),%edx + 2aa: 56 push %esi + 2ab: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 2ae: 85 c0 test %eax,%eax + 2b0: 7e 13 jle 2c5 + 2b2: 01 d0 add %edx,%eax + dst = vdst; + 2b4: 89 d7 mov %edx,%edi + 2b6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2bd: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 2c0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 2c1: 39 f8 cmp %edi,%eax + 2c3: 75 fb jne 2c0 + } + return vdst; +} + 2c5: 5e pop %esi + 2c6: 89 d0 mov %edx,%eax + 2c8: 5f pop %edi + 2c9: 5d pop %ebp + 2ca: c3 ret + +000002cb : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 2cb: b8 01 00 00 00 mov $0x1,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(exit) + 2d3: b8 02 00 00 00 mov $0x2,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(wait) + 2db: b8 03 00 00 00 mov $0x3,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(pipe) + 2e3: b8 04 00 00 00 mov $0x4,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(read) + 2eb: b8 05 00 00 00 mov $0x5,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(kill) + 2f3: b8 06 00 00 00 mov $0x6,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(exec) + 2fb: b8 07 00 00 00 mov $0x7,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(fstat) + 303: b8 08 00 00 00 mov $0x8,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(chdir) + 30b: b8 09 00 00 00 mov $0x9,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(dup) + 313: b8 0a 00 00 00 mov $0xa,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(getpid) + 31b: b8 0b 00 00 00 mov $0xb,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(sbrk) + 323: b8 0c 00 00 00 mov $0xc,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(sleep) + 32b: b8 0d 00 00 00 mov $0xd,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(uptime) + 333: b8 0e 00 00 00 mov $0xe,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(open) + 33b: b8 0f 00 00 00 mov $0xf,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(write) + 343: b8 10 00 00 00 mov $0x10,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(mknod) + 34b: b8 11 00 00 00 mov $0x11,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(unlink) + 353: b8 12 00 00 00 mov $0x12,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(link) + 35b: b8 13 00 00 00 mov $0x13,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(mkdir) + 363: b8 14 00 00 00 mov $0x14,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + +0000036b : +SYSCALL(close) + 36b: b8 15 00 00 00 mov $0x15,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(getch) + 373: b8 16 00 00 00 mov $0x16,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + +0000037b : +SYSCALL(greeting) + 37b: b8 17 00 00 00 mov $0x17,%eax + 380: cd 40 int $0x40 + 382: c3 ret + +00000383 : +SYSCALL(shutdown) + 383: b8 18 00 00 00 mov $0x18,%eax + 388: cd 40 int $0x40 + 38a: c3 ret + 38b: 66 90 xchg %ax,%ax + 38d: 66 90 xchg %ax,%ax + 38f: 90 nop + +00000390 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 390: 55 push %ebp + 391: 89 e5 mov %esp,%ebp + 393: 57 push %edi + 394: 56 push %esi + 395: 53 push %ebx + 396: 83 ec 3c sub $0x3c,%esp + 399: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 39c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 39e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 3a1: 85 d2 test %edx,%edx + 3a3: 0f 89 7f 00 00 00 jns 428 + 3a9: f6 45 08 01 testb $0x1,0x8(%ebp) + 3ad: 74 79 je 428 + neg = 1; + 3af: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 3b6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 3b8: 31 db xor %ebx,%ebx + 3ba: 8d 75 d7 lea -0x29(%ebp),%esi + 3bd: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 3c0: 89 c8 mov %ecx,%eax + 3c2: 31 d2 xor %edx,%edx + 3c4: 89 cf mov %ecx,%edi + 3c6: f7 75 c4 divl -0x3c(%ebp) + 3c9: 0f b6 92 fc 07 00 00 movzbl 0x7fc(%edx),%edx + 3d0: 89 45 c0 mov %eax,-0x40(%ebp) + 3d3: 89 d8 mov %ebx,%eax + 3d5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3d8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3db: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3de: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3e1: 76 dd jbe 3c0 + if (neg) { + 3e3: 8b 4d bc mov -0x44(%ebp),%ecx + 3e6: 85 c9 test %ecx,%ecx + 3e8: 74 0c je 3f6 + buf[i++] = '-'; + 3ea: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3ef: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 3f1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 3f6: 8b 7d b8 mov -0x48(%ebp),%edi + 3f9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 3fd: eb 07 jmp 406 + 3ff: 90 nop + putc(fd, buf[i]); + 400: 0f b6 13 movzbl (%ebx),%edx + 403: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 406: 83 ec 04 sub $0x4,%esp + 409: 88 55 d7 mov %dl,-0x29(%ebp) + 40c: 6a 01 push $0x1 + 40e: 56 push %esi + 40f: 57 push %edi + 410: e8 2e ff ff ff call 343 + while (--i >= 0) { + 415: 83 c4 10 add $0x10,%esp + 418: 39 de cmp %ebx,%esi + 41a: 75 e4 jne 400 + } +} + 41c: 8d 65 f4 lea -0xc(%ebp),%esp + 41f: 5b pop %ebx + 420: 5e pop %esi + 421: 5f pop %edi + 422: 5d pop %ebp + 423: c3 ret + 424: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 428: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 42f: eb 87 jmp 3b8 + 431: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 438: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 43f: 90 nop + +00000440 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 440: 55 push %ebp + 441: 89 e5 mov %esp,%ebp + 443: 57 push %edi + 444: 56 push %esi + 445: 53 push %ebx + 446: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 449: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 44c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 44f: 0f b6 13 movzbl (%ebx),%edx + 452: 84 d2 test %dl,%dl + 454: 74 6a je 4c0 + ap = (uint*)(void*)&fmt + 1; + 456: 8d 45 10 lea 0x10(%ebp),%eax + 459: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 45c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 45f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 461: 89 45 d0 mov %eax,-0x30(%ebp) + 464: eb 36 jmp 49c + 466: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 46d: 8d 76 00 lea 0x0(%esi),%esi + 470: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 473: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 478: 83 f8 25 cmp $0x25,%eax + 47b: 74 15 je 492 + write(fd, &c, 1); + 47d: 83 ec 04 sub $0x4,%esp + 480: 88 55 e7 mov %dl,-0x19(%ebp) + 483: 6a 01 push $0x1 + 485: 57 push %edi + 486: 56 push %esi + 487: e8 b7 fe ff ff call 343 + 48c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 48f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 492: 0f b6 13 movzbl (%ebx),%edx + 495: 83 c3 01 add $0x1,%ebx + 498: 84 d2 test %dl,%dl + 49a: 74 24 je 4c0 + c = fmt[i] & 0xff; + 49c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 49f: 85 c9 test %ecx,%ecx + 4a1: 74 cd je 470 + } + } + else if (state == '%') { + 4a3: 83 f9 25 cmp $0x25,%ecx + 4a6: 75 ea jne 492 + if (c == 'd') { + 4a8: 83 f8 25 cmp $0x25,%eax + 4ab: 0f 84 07 01 00 00 je 5b8 + 4b1: 83 e8 63 sub $0x63,%eax + 4b4: 83 f8 15 cmp $0x15,%eax + 4b7: 77 17 ja 4d0 + 4b9: ff 24 85 a4 07 00 00 jmp *0x7a4(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 4c0: 8d 65 f4 lea -0xc(%ebp),%esp + 4c3: 5b pop %ebx + 4c4: 5e pop %esi + 4c5: 5f pop %edi + 4c6: 5d pop %ebp + 4c7: c3 ret + 4c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4cf: 90 nop + write(fd, &c, 1); + 4d0: 83 ec 04 sub $0x4,%esp + 4d3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4d6: 6a 01 push $0x1 + 4d8: 57 push %edi + 4d9: 56 push %esi + 4da: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4de: e8 60 fe ff ff call 343 + putc(fd, c); + 4e3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4e7: 83 c4 0c add $0xc,%esp + 4ea: 88 55 e7 mov %dl,-0x19(%ebp) + 4ed: 6a 01 push $0x1 + 4ef: 57 push %edi + 4f0: 56 push %esi + 4f1: e8 4d fe ff ff call 343 + putc(fd, c); + 4f6: 83 c4 10 add $0x10,%esp + state = 0; + 4f9: 31 c9 xor %ecx,%ecx + 4fb: eb 95 jmp 492 + 4fd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 500: 83 ec 0c sub $0xc,%esp + 503: b9 10 00 00 00 mov $0x10,%ecx + 508: 6a 00 push $0x0 + 50a: 8b 45 d0 mov -0x30(%ebp),%eax + 50d: 8b 10 mov (%eax),%edx + 50f: 89 f0 mov %esi,%eax + 511: e8 7a fe ff ff call 390 + ap++; + 516: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 51a: 83 c4 10 add $0x10,%esp + state = 0; + 51d: 31 c9 xor %ecx,%ecx + 51f: e9 6e ff ff ff jmp 492 + 524: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 528: 8b 45 d0 mov -0x30(%ebp),%eax + 52b: 8b 10 mov (%eax),%edx + ap++; + 52d: 83 c0 04 add $0x4,%eax + 530: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 533: 85 d2 test %edx,%edx + 535: 0f 84 8d 00 00 00 je 5c8 + while (*s != 0) { + 53b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 53e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 540: 84 c0 test %al,%al + 542: 0f 84 4a ff ff ff je 492 + 548: 89 5d d4 mov %ebx,-0x2c(%ebp) + 54b: 89 d3 mov %edx,%ebx + 54d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 550: 83 ec 04 sub $0x4,%esp + s++; + 553: 83 c3 01 add $0x1,%ebx + 556: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 559: 6a 01 push $0x1 + 55b: 57 push %edi + 55c: 56 push %esi + 55d: e8 e1 fd ff ff call 343 + while (*s != 0) { + 562: 0f b6 03 movzbl (%ebx),%eax + 565: 83 c4 10 add $0x10,%esp + 568: 84 c0 test %al,%al + 56a: 75 e4 jne 550 + state = 0; + 56c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 56f: 31 c9 xor %ecx,%ecx + 571: e9 1c ff ff ff jmp 492 + 576: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 57d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 580: 83 ec 0c sub $0xc,%esp + 583: b9 0a 00 00 00 mov $0xa,%ecx + 588: 6a 01 push $0x1 + 58a: e9 7b ff ff ff jmp 50a + 58f: 90 nop + putc(fd, *ap); + 590: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 593: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 596: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 598: 6a 01 push $0x1 + 59a: 57 push %edi + 59b: 56 push %esi + putc(fd, *ap); + 59c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 59f: e8 9f fd ff ff call 343 + ap++; + 5a4: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 5a8: 83 c4 10 add $0x10,%esp + state = 0; + 5ab: 31 c9 xor %ecx,%ecx + 5ad: e9 e0 fe ff ff jmp 492 + 5b2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 5b8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 5bb: 83 ec 04 sub $0x4,%esp + 5be: e9 2a ff ff ff jmp 4ed + 5c3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 5c7: 90 nop + s = "(null)"; + 5c8: ba 9b 07 00 00 mov $0x79b,%edx + while (*s != 0) { + 5cd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5d0: b8 28 00 00 00 mov $0x28,%eax + 5d5: 89 d3 mov %edx,%ebx + 5d7: e9 74 ff ff ff jmp 550 + 5dc: 66 90 xchg %ax,%ax + 5de: 66 90 xchg %ax,%ax + +000005e0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5e0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5e1: a1 b4 0a 00 00 mov 0xab4,%eax +void free(void *ap) { + 5e6: 89 e5 mov %esp,%ebp + 5e8: 57 push %edi + 5e9: 56 push %esi + 5ea: 53 push %ebx + 5eb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5ee: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5f8: 89 c2 mov %eax,%edx + 5fa: 8b 00 mov (%eax),%eax + 5fc: 39 ca cmp %ecx,%edx + 5fe: 73 30 jae 630 + 600: 39 c1 cmp %eax,%ecx + 602: 72 04 jb 608 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 604: 39 c2 cmp %eax,%edx + 606: 72 f0 jb 5f8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 608: 8b 73 fc mov -0x4(%ebx),%esi + 60b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 60e: 39 f8 cmp %edi,%eax + 610: 74 30 je 642 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 612: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 615: 8b 42 04 mov 0x4(%edx),%eax + 618: 8d 34 c2 lea (%edx,%eax,8),%esi + 61b: 39 f1 cmp %esi,%ecx + 61d: 74 3a je 659 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 61f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 621: 5b pop %ebx + freep = p; + 622: 89 15 b4 0a 00 00 mov %edx,0xab4 +} + 628: 5e pop %esi + 629: 5f pop %edi + 62a: 5d pop %ebp + 62b: c3 ret + 62c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 630: 39 c2 cmp %eax,%edx + 632: 72 c4 jb 5f8 + 634: 39 c1 cmp %eax,%ecx + 636: 73 c0 jae 5f8 + if (bp + bp->s.size == p->s.ptr) { + 638: 8b 73 fc mov -0x4(%ebx),%esi + 63b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 63e: 39 f8 cmp %edi,%eax + 640: 75 d0 jne 612 + bp->s.size += p->s.ptr->s.size; + 642: 03 70 04 add 0x4(%eax),%esi + 645: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 648: 8b 02 mov (%edx),%eax + 64a: 8b 00 mov (%eax),%eax + 64c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 64f: 8b 42 04 mov 0x4(%edx),%eax + 652: 8d 34 c2 lea (%edx,%eax,8),%esi + 655: 39 f1 cmp %esi,%ecx + 657: 75 c6 jne 61f + p->s.size += bp->s.size; + 659: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 65c: 89 15 b4 0a 00 00 mov %edx,0xab4 + p->s.size += bp->s.size; + 662: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 665: 8b 4b f8 mov -0x8(%ebx),%ecx + 668: 89 0a mov %ecx,(%edx) +} + 66a: 5b pop %ebx + 66b: 5e pop %esi + 66c: 5f pop %edi + 66d: 5d pop %ebp + 66e: c3 ret + 66f: 90 nop + +00000670 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 670: 55 push %ebp + 671: 89 e5 mov %esp,%ebp + 673: 57 push %edi + 674: 56 push %esi + 675: 53 push %ebx + 676: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 679: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 67c: 8b 3d b4 0a 00 00 mov 0xab4,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 682: 8d 70 07 lea 0x7(%eax),%esi + 685: c1 ee 03 shr $0x3,%esi + 688: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 68b: 85 ff test %edi,%edi + 68d: 0f 84 9d 00 00 00 je 730 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 693: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 695: 8b 4a 04 mov 0x4(%edx),%ecx + 698: 39 f1 cmp %esi,%ecx + 69a: 73 6a jae 706 + 69c: bb 00 10 00 00 mov $0x1000,%ebx + 6a1: 39 de cmp %ebx,%esi + 6a3: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 6a6: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 6ad: 89 45 e4 mov %eax,-0x1c(%ebp) + 6b0: eb 17 jmp 6c9 + 6b2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6b8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 6ba: 8b 48 04 mov 0x4(%eax),%ecx + 6bd: 39 f1 cmp %esi,%ecx + 6bf: 73 4f jae 710 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 6c1: 8b 3d b4 0a 00 00 mov 0xab4,%edi + 6c7: 89 c2 mov %eax,%edx + 6c9: 39 d7 cmp %edx,%edi + 6cb: 75 eb jne 6b8 + p = sbrk(nu * sizeof(Header)); + 6cd: 83 ec 0c sub $0xc,%esp + 6d0: ff 75 e4 push -0x1c(%ebp) + 6d3: e8 4b fc ff ff call 323 + if (p == (char*)-1) { + 6d8: 83 c4 10 add $0x10,%esp + 6db: 83 f8 ff cmp $0xffffffff,%eax + 6de: 74 1c je 6fc + hp->s.size = nu; + 6e0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6e3: 83 ec 0c sub $0xc,%esp + 6e6: 83 c0 08 add $0x8,%eax + 6e9: 50 push %eax + 6ea: e8 f1 fe ff ff call 5e0 + return freep; + 6ef: 8b 15 b4 0a 00 00 mov 0xab4,%edx + if ((p = morecore(nunits)) == 0) { + 6f5: 83 c4 10 add $0x10,%esp + 6f8: 85 d2 test %edx,%edx + 6fa: 75 bc jne 6b8 + return 0; + } + } + } +} + 6fc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 6ff: 31 c0 xor %eax,%eax +} + 701: 5b pop %ebx + 702: 5e pop %esi + 703: 5f pop %edi + 704: 5d pop %ebp + 705: c3 ret + if (p->s.size >= nunits) { + 706: 89 d0 mov %edx,%eax + 708: 89 fa mov %edi,%edx + 70a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 710: 39 ce cmp %ecx,%esi + 712: 74 4c je 760 + p->s.size -= nunits; + 714: 29 f1 sub %esi,%ecx + 716: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 719: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 71c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 71f: 89 15 b4 0a 00 00 mov %edx,0xab4 +} + 725: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 728: 83 c0 08 add $0x8,%eax +} + 72b: 5b pop %ebx + 72c: 5e pop %esi + 72d: 5f pop %edi + 72e: 5d pop %ebp + 72f: c3 ret + base.s.ptr = freep = prevp = &base; + 730: c7 05 b4 0a 00 00 b8 movl $0xab8,0xab4 + 737: 0a 00 00 + base.s.size = 0; + 73a: bf b8 0a 00 00 mov $0xab8,%edi + base.s.ptr = freep = prevp = &base; + 73f: c7 05 b8 0a 00 00 b8 movl $0xab8,0xab8 + 746: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 749: 89 fa mov %edi,%edx + base.s.size = 0; + 74b: c7 05 bc 0a 00 00 00 movl $0x0,0xabc + 752: 00 00 00 + if (p->s.size >= nunits) { + 755: e9 42 ff ff ff jmp 69c + 75a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 760: 8b 08 mov (%eax),%ecx + 762: 89 0a mov %ecx,(%edx) + 764: eb b9 jmp 71f diff --git a/mkdir.c b/mkdir.c new file mode 100644 index 0000000..c83dc84 --- /dev/null +++ b/mkdir.c @@ -0,0 +1,21 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + int i; + + if (argc < 2) { + printf(2, "Usage: mkdir files...\n"); + exit(); + } + + for (i = 1; i < argc; i++) { + if (mkdir(argv[i]) < 0) { + printf(2, "mkdir: %s failed to create\n", argv[i]); + break; + } + } + + exit(); +} diff --git a/mkdir.d b/mkdir.d new file mode 100644 index 0000000..0c77808 --- /dev/null +++ b/mkdir.d @@ -0,0 +1 @@ +mkdir.o: mkdir.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/mkdir.o b/mkdir.o new file mode 100644 index 0000000..e93daa9 Binary files /dev/null and b/mkdir.o differ diff --git a/mkdir.sym b/mkdir.sym new file mode 100644 index 0000000..bd7fb75 --- /dev/null +++ b/mkdir.sym @@ -0,0 +1,48 @@ +00000000 mkdir.c +00000000 ulib.c +00000000 printf.c +00000390 printint +000007fc digits.0 +00000000 umalloc.c +00000ab4 freep +00000ab8 base +00000080 strcpy +00000440 printf +0000037b greeting +000002a0 memmove +0000034b mknod +000001a0 gets +0000031b getpid +00000670 malloc +0000032b sleep +000002e3 pipe +00000373 getch +00000343 write +00000303 fstat +000002f3 kill +0000030b chdir +000002fb exec +000002db wait +000002eb read +00000353 unlink +000002cb fork +00000323 sbrk +00000333 uptime +00000ab4 __bss_start +00000140 memset +00000000 main +000000b0 strcmp +00000383 shutdown +00000313 dup +00000210 stat +00000ab4 _edata +00000ac0 _end +0000035b link +000002d3 exit +00000260 atoi +00000110 strlen +0000033b open +00000160 strchr +00000363 mkdir +0000036b close +000005e0 free diff --git a/mkfs b/mkfs new file mode 100644 index 0000000..d536cc4 Binary files /dev/null and b/mkfs differ diff --git a/mkfs.c b/mkfs.c new file mode 100644 index 0000000..a970b77 --- /dev/null +++ b/mkfs.c @@ -0,0 +1,283 @@ +#include +#include +#include +#include +#include +#include + +#define stat xv6_stat // avoid clash with host struct stat +#include "types.h" +#include "fs.h" +#include "stat.h" +#include "param.h" + +#ifndef static_assert +#define static_assert(a, b) do { switch (0) case 0: \ + case (a): \ + ; } while (0) +#endif + +#define NINODES 200 + +// Disk layout: +// [ boot block | sb block | log | inode blocks | free bit map | data blocks ] + +int nbitmap = FSSIZE / (BSIZE * 8) + 1; +int ninodeblocks = NINODES / IPB + 1; +int nlog = LOGSIZE; +int nmeta; // Number of meta blocks (boot, sb, nlog, inode, bitmap) +int nblocks; // Number of data blocks + +int fsfd; +struct superblock sb; +char zeroes[BSIZE]; +uint freeinode = 1; +uint freeblock; + + +void balloc(int); +void wsect(uint, void*); +void winode(uint, struct dinode*); +void rinode(uint inum, struct dinode *ip); +void rsect(uint sec, void *buf); +uint ialloc(ushort type); +void iappend(uint inum, void *p, int n); + +// convert to intel byte order +ushort xshort(ushort x) { + ushort y; + uchar *a = (uchar*)&y; + a[0] = x; + a[1] = x >> 8; + return y; +} + +uint xint(uint x) { + uint y; + uchar *a = (uchar*)&y; + a[0] = x; + a[1] = x >> 8; + a[2] = x >> 16; + a[3] = x >> 24; + return y; +} + +int main(int argc, char *argv[]) { + int i, cc, fd; + uint rootino, inum, off; + struct dirent de; + char buf[BSIZE]; + struct dinode din; + + + static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); + + if (argc < 2) { + fprintf(stderr, "Usage: mkfs fs.img files...\n"); + exit(1); + } + + assert((BSIZE % sizeof(struct dinode)) == 0); + assert((BSIZE % sizeof(struct dirent)) == 0); + + fsfd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666); + if (fsfd < 0) { + perror(argv[1]); + exit(1); + } + + // 1 fs block = 1 disk sector + nmeta = 2 + nlog + ninodeblocks + nbitmap; + nblocks = FSSIZE - nmeta; + + sb.size = xint(FSSIZE); + sb.nblocks = xint(nblocks); + sb.ninodes = xint(NINODES); + sb.nlog = xint(nlog); + sb.logstart = xint(2); + sb.inodestart = xint(2 + nlog); + sb.bmapstart = xint(2 + nlog + ninodeblocks); + + printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", + nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); + + freeblock = nmeta; // the first free block that we can allocate + + for (i = 0; i < FSSIZE; i++) { + wsect(i, zeroes); + } + + memset(buf, 0, sizeof(buf)); + memmove(buf, &sb, sizeof(sb)); + wsect(1, buf); + + rootino = ialloc(T_DIR); + assert(rootino == ROOTINO); + + bzero(&de, sizeof(de)); + de.inum = xshort(rootino); + strcpy(de.name, "."); + iappend(rootino, &de, sizeof(de)); + + bzero(&de, sizeof(de)); + de.inum = xshort(rootino); + strcpy(de.name, ".."); + iappend(rootino, &de, sizeof(de)); + + for (i = 2; i < argc; i++) { + assert(index(argv[i], '/') == 0); + + if ((fd = open(argv[i], 0)) < 0) { + perror(argv[i]); + exit(1); + } + + // Skip leading _ in name when writing to file system. + // The binaries are named _rm, _cat, etc. to keep the + // build operating system from trying to execute them + // in place of system binaries like rm and cat. + if (argv[i][0] == '_') { + ++argv[i]; + } + + inum = ialloc(T_FILE); + + bzero(&de, sizeof(de)); + de.inum = xshort(inum); + strncpy(de.name, argv[i], DIRSIZ); + iappend(rootino, &de, sizeof(de)); + + while ((cc = read(fd, buf, sizeof(buf))) > 0) { + iappend(inum, buf, cc); + } + + close(fd); + } + + // fix size of root inode dir + rinode(rootino, &din); + off = xint(din.size); + off = ((off / BSIZE) + 1) * BSIZE; + din.size = xint(off); + winode(rootino, &din); + + balloc(freeblock); + + exit(0); +} + +void wsect(uint sec, void *buf) { + if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE) { + perror("lseek"); + exit(1); + } + if (write(fsfd, buf, BSIZE) != BSIZE) { + perror("write"); + exit(1); + } +} + +void winode(uint inum, struct dinode *ip) { + char buf[BSIZE]; + uint bn; + struct dinode *dip; + + bn = IBLOCK(inum, sb); + rsect(bn, buf); + dip = ((struct dinode*)buf) + (inum % IPB); + *dip = *ip; + wsect(bn, buf); +} + +void rinode(uint inum, struct dinode *ip) { + char buf[BSIZE]; + uint bn; + struct dinode *dip; + + bn = IBLOCK(inum, sb); + rsect(bn, buf); + dip = ((struct dinode*)buf) + (inum % IPB); + *ip = *dip; +} + +void rsect(uint sec, void *buf) { + if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE) { + perror("lseek"); + exit(1); + } + if (read(fsfd, buf, BSIZE) != BSIZE) { + perror("read"); + exit(1); + } +} + +uint ialloc(ushort type) { + uint inum = freeinode++; + struct dinode din; + + bzero(&din, sizeof(din)); + din.type = xshort(type); + din.nlink = xshort(1); + din.size = xint(0); + winode(inum, &din); + return inum; +} + +void balloc(int used) { + uchar buf[BSIZE]; + int i; + + printf("balloc: first %d blocks have been allocated\n", used); + assert(used < BSIZE * 8); + bzero(buf, BSIZE); + for (i = 0; i < used; i++) { + buf[i / 8] = buf[i / 8] | (0x1 << (i % 8)); + } + printf("balloc: write bitmap block at sector %d\n", sb.bmapstart); + wsect(sb.bmapstart, buf); +} + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +void iappend(uint inum, void *xp, int n) { + char *p = (char*)xp; + uint fbn, off, n1; + struct dinode din; + char buf[BSIZE]; + uint indirect[NINDIRECT]; + uint x; + + rinode(inum, &din); + off = xint(din.size); + // printf("append inum %d at off %d sz %d\n", inum, off, n); + while (n > 0) { + fbn = off / BSIZE; + assert(fbn < MAXFILE); + if (fbn < NDIRECT) { + if (xint(din.addrs[fbn]) == 0) { + din.addrs[fbn] = xint(freeblock++); + } + x = xint(din.addrs[fbn]); + } + else { + if (xint(din.addrs[NDIRECT]) == 0) { + din.addrs[NDIRECT] = xint(freeblock++); + } + rsect(xint(din.addrs[NDIRECT]), (char*)indirect); + if (indirect[fbn - NDIRECT] == 0) { + indirect[fbn - NDIRECT] = xint(freeblock++); + wsect(xint(din.addrs[NDIRECT]), (char*)indirect); + } + x = xint(indirect[fbn - NDIRECT]); + } + n1 = min(n, (fbn + 1) * BSIZE - off); + rsect(x, buf); + bcopy(p, buf + off - (fbn * BSIZE), n1); + wsect(x, buf); + n -= n1; + off += n1; + p += n1; + } + din.size = xint(off); + winode(inum, &din); +} diff --git a/mmu.h b/mmu.h new file mode 100644 index 0000000..b126119 --- /dev/null +++ b/mmu.h @@ -0,0 +1,181 @@ +// This file contains definitions for the +// x86 memory management unit (MMU). + +// Eflags register +#define FL_IF 0x00000200 // Interrupt Enable + +// Control Register flags +#define CR0_PE 0x00000001 // Protection Enable +#define CR0_WP 0x00010000 // Write Protect +#define CR0_PG 0x80000000 // Paging + +#define CR4_PSE 0x00000010 // Page size extension + +// various segment selectors. +#define SEG_KCODE 1 // kernel code +#define SEG_KDATA 2 // kernel data+stack +#define SEG_UCODE 3 // user code +#define SEG_UDATA 4 // user data+stack +#define SEG_TSS 5 // this process's task state + +// cpu->gdt[NSEGS] holds the above segments. +#define NSEGS 6 + +#ifndef __ASSEMBLER__ +// Segment Descriptor +struct segdesc { + uint lim_15_0 : 16; // Low bits of segment limit + uint base_15_0 : 16; // Low bits of segment base address + uint base_23_16 : 8; // Middle bits of segment base address + uint type : 4; // Segment type (see STS_ constants) + uint s : 1; // 0 = system, 1 = application + uint dpl : 2; // Descriptor Privilege Level + uint p : 1; // Present + uint lim_19_16 : 4; // High bits of segment limit + uint avl : 1; // Unused (available for software use) + uint rsv1 : 1; // Reserved + uint db : 1; // 0 = 16-bit segment, 1 = 32-bit segment + uint g : 1; // Granularity: limit scaled by 4K when set + uint base_31_24 : 8; // High bits of segment base address +}; + +// Normal segment +#define SEG(type, base, lim, dpl) (struct segdesc) \ + { ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \ + ((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \ + (uint)(lim) >> 28, 0, 0, 1, 1, (uint)(base) >> 24 } +#define SEG16(type, base, lim, dpl) (struct segdesc) \ + { (lim) & 0xffff, (uint)(base) & 0xffff, \ + ((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \ + (uint)(lim) >> 16, 0, 0, 1, 0, (uint)(base) >> 24 } +#endif + +#define DPL_USER 0x3 // User DPL + +// Application segment type bits +#define STA_X 0x8 // Executable segment +#define STA_W 0x2 // Writeable (non-executable segments) +#define STA_R 0x2 // Readable (executable segments) + +// System segment type bits +#define STS_T32A 0x9 // Available 32-bit TSS +#define STS_IG32 0xE // 32-bit Interrupt Gate +#define STS_TG32 0xF // 32-bit Trap Gate + +// A virtual address 'la' has a three-part structure as follows: +// +// +--------10------+-------10-------+---------12----------+ +// | Page Directory | Page Table | Offset within Page | +// | Index | Index | | +// +----------------+----------------+---------------------+ +// \--- PDX(va) --/ \--- PTX(va) --/ + +// page directory index +#define PDX(va) (((uint)(va) >> PDXSHIFT) & 0x3FF) + +// page table index +#define PTX(va) (((uint)(va) >> PTXSHIFT) & 0x3FF) + +// construct virtual address from indexes and offset +#define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) + +// Page directory and page table constants. +#define NPDENTRIES 1024 // # directory entries per page directory +#define NPTENTRIES 1024 // # PTEs per page table +#define PGSIZE 4096 // bytes mapped by a page + +#define PTXSHIFT 12 // offset of PTX in a linear address +#define PDXSHIFT 22 // offset of PDX in a linear address + +#define PGROUNDUP(sz) (((sz) + PGSIZE - 1) & ~(PGSIZE - 1)) +#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE - 1)) + +// Page table/directory entry flags. +#define PTE_P 0x001 // Present +#define PTE_W 0x002 // Writeable +#define PTE_U 0x004 // User +#define PTE_PS 0x080 // Page Size + +// Address in page table or page directory entry +#define PTE_ADDR(pte) ((uint)(pte) & ~0xFFF) +#define PTE_FLAGS(pte) ((uint)(pte) & 0xFFF) + +#ifndef __ASSEMBLER__ +typedef uint pte_t; + +// Task state segment format +struct taskstate { + uint link; // Old ts selector + uint esp0; // Stack pointers and segment selectors + ushort ss0; // after an increase in privilege level + ushort padding1; + uint *esp1; + ushort ss1; + ushort padding2; + uint *esp2; + ushort ss2; + ushort padding3; + void *cr3; // Page directory base + uint *eip; // Saved state from last task switch + uint eflags; + uint eax; // More saved state (registers) + uint ecx; + uint edx; + uint ebx; + uint *esp; + uint *ebp; + uint esi; + uint edi; + ushort es; // Even more saved state (segment selectors) + ushort padding4; + ushort cs; + ushort padding5; + ushort ss; + ushort padding6; + ushort ds; + ushort padding7; + ushort fs; + ushort padding8; + ushort gs; + ushort padding9; + ushort ldt; + ushort padding10; + ushort t; // Trap on task switch + ushort iomb; // I/O map base address +}; + +// Gate descriptors for interrupts and traps +struct gatedesc { + uint off_15_0 : 16; // low 16 bits of offset in segment + uint cs : 16; // code segment selector + uint args : 5; // # args, 0 for interrupt/trap gates + uint rsv1 : 3; // reserved(should be zero I guess) + uint type : 4; // type(STS_{IG32,TG32}) + uint s : 1; // must be 0 (system) + uint dpl : 2; // descriptor(meaning new) privilege level + uint p : 1; // Present + uint off_31_16 : 16; // high bits of offset in segment +}; + +// Set up a normal interrupt/trap gate descriptor. +// - istrap: 1 for a trap (= exception) gate, 0 for an interrupt gate. +// interrupt gate clears FL_IF, trap gate leaves FL_IF alone +// - sel: Code segment selector for interrupt/trap handler +// - off: Offset in code segment for interrupt/trap handler +// - dpl: Descriptor Privilege Level - +// the privilege level required for software to invoke +// this interrupt/trap gate explicitly using an int instruction. +#define SETGATE(gate, istrap, sel, off, d) \ + { \ + (gate).off_15_0 = (uint)(off) & 0xffff; \ + (gate).cs = (sel); \ + (gate).args = 0; \ + (gate).rsv1 = 0; \ + (gate).type = (istrap) ? STS_TG32 : STS_IG32; \ + (gate).s = 0; \ + (gate).dpl = (d); \ + (gate).p = 1; \ + (gate).off_31_16 = (uint)(off) >> 16; \ + } + +#endif diff --git a/mp.c b/mp.c new file mode 100644 index 0000000..bb1454d --- /dev/null +++ b/mp.c @@ -0,0 +1,141 @@ +// Multiprocessor support +// Search memory for MP description structures. +// http://developer.intel.com/design/pentium/datashts/24201606.pdf + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mp.h" +#include "x86.h" +#include "mmu.h" +#include "proc.h" + +struct cpu cpus[NCPU]; +int ncpu; +uchar ioapicid; + +static uchar sum(uchar *addr, int len) { + int i, sum; + + sum = 0; + for (i = 0; i < len; i++) { + sum += addr[i]; + } + return sum; +} + +// Look for an MP structure in the len bytes at addr. +static struct mp*mpsearch1(uint a, int len) { + uchar *e, *p, *addr; + + addr = P2V(a); + e = addr + len; + for (p = addr; p < e; p += sizeof(struct mp)) { + if (memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0) { + return (struct mp*)p; + } + } + return 0; +} + +// Search for the MP Floating Pointer Structure, which according to the +// spec is in one of the following three locations: +// 1) in the first KB of the EBDA; +// 2) in the last KB of system base memory; +// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF. +static struct mp*mpsearch(void) { + uchar *bda; + uint p; + struct mp *mp; + + bda = (uchar *) P2V(0x400); + if ((p = ((bda[0x0F] << 8) | bda[0x0E]) << 4)) { + if ((mp = mpsearch1(p, 1024))) { + return mp; + } + } + else { + p = ((bda[0x14] << 8) | bda[0x13]) * 1024; + if ((mp = mpsearch1(p - 1024, 1024))) { + return mp; + } + } + return mpsearch1(0xF0000, 0x10000); +} + +// Search for an MP configuration table. For now, +// don't accept the default configurations (physaddr == 0). +// Check for correct signature, calculate the checksum and, +// if correct, check the version. +// To do: check extended table checksum. +static struct mpconf*mpconfig(struct mp **pmp) { + struct mpconf *conf; + struct mp *mp; + + if ((mp = mpsearch()) == 0 || mp->physaddr == 0) { + return 0; + } + conf = (struct mpconf*) P2V((uint) mp->physaddr); + if (memcmp(conf, "PCMP", 4) != 0) { + return 0; + } + if (conf->version != 1 && conf->version != 4) { + return 0; + } + if (sum((uchar*)conf, conf->length) != 0) { + return 0; + } + *pmp = mp; + return conf; +} + +void mpinit(void) { + uchar *p, *e; + int ismp; + struct mp *mp; + struct mpconf *conf; + struct mpproc *proc; + struct mpioapic *ioapic; + + if ((conf = mpconfig(&mp)) == 0) { + panic("Expect to run on an SMP"); + } + ismp = 1; + lapic = (uint*)conf->lapicaddr; + for (p = (uchar*)(conf + 1), e = (uchar*)conf + conf->length; p < e;) { + switch (*p) { + case MPPROC: + proc = (struct mpproc*)p; + if (ncpu < NCPU) { + cpus[ncpu].apicid = proc->apicid; // apicid may differ from ncpu + ncpu++; + } + p += sizeof(struct mpproc); + continue; + case MPIOAPIC: + ioapic = (struct mpioapic*)p; + ioapicid = ioapic->apicno; + p += sizeof(struct mpioapic); + continue; + case MPBUS: + case MPIOINTR: + case MPLINTR: + p += 8; + continue; + default: + ismp = 0; + break; + } + } + if (!ismp) { + panic("Didn't find a suitable machine"); + } + + if (mp->imcrp) { + // Bochs doesn't support IMCR, so this doesn't run on Bochs. + // But it would on real hardware. + outb(0x22, 0x70); // Select IMCR + outb(0x23, inb(0x23) | 1); // Mask external interrupts. + } +} diff --git a/mp.d b/mp.d new file mode 100644 index 0000000..0714441 --- /dev/null +++ b/mp.d @@ -0,0 +1,2 @@ +mp.o: mp.c /usr/include/stdc-predef.h types.h defs.h param.h memlayout.h \ + mp.h x86.h mmu.h proc.h diff --git a/mp.h b/mp.h new file mode 100644 index 0000000..c316dde --- /dev/null +++ b/mp.h @@ -0,0 +1,56 @@ +// See MultiProcessor Specification Version 1.[14] + +struct mp { // floating pointer + uchar signature[4]; // "_MP_" + void *physaddr; // phys addr of MP config table + uchar length; // 1 + uchar specrev; // [14] + uchar checksum; // all bytes must add up to 0 + uchar type; // MP system config type + uchar imcrp; + uchar reserved[3]; +}; + +struct mpconf { // configuration table header + uchar signature[4]; // "PCMP" + ushort length; // total table length + uchar version; // [14] + uchar checksum; // all bytes must add up to 0 + uchar product[20]; // product id + uint *oemtable; // OEM table pointer + ushort oemlength; // OEM table length + ushort entry; // entry count + uint *lapicaddr; // address of local APIC + ushort xlength; // extended table length + uchar xchecksum; // extended table checksum + uchar reserved; +}; + +struct mpproc { // processor table entry + uchar type; // entry type (0) + uchar apicid; // local APIC id + uchar version; // local APIC verison + uchar flags; // CPU flags + #define MPBOOT 0x02 // This proc is the bootstrap processor. + uchar signature[4]; // CPU signature + uint feature; // feature flags from CPUID instruction + uchar reserved[8]; +}; + +struct mpioapic { // I/O APIC table entry + uchar type; // entry type (2) + uchar apicno; // I/O APIC id + uchar version; // I/O APIC version + uchar flags; // I/O APIC flags + uint *addr; // I/O APIC address +}; + +// Table entry types +#define MPPROC 0x00 // One per processor +#define MPBUS 0x01 // One per bus +#define MPIOAPIC 0x02 // One per I/O APIC +#define MPIOINTR 0x03 // One per bus interrupt source +#define MPLINTR 0x04 // One per system interrupt source + + + diff --git a/mp.o b/mp.o new file mode 100644 index 0000000..b92affd Binary files /dev/null and b/mp.o differ diff --git a/param.h b/param.h new file mode 100644 index 0000000..cc8ac1e --- /dev/null +++ b/param.h @@ -0,0 +1,14 @@ +#define NPROC 64 // maximum number of processes +#define KSTACKSIZE 4096 // size of per-process kernel stack +#define NCPU 8 // maximum number of CPUs +#define NOFILE 16 // open files per process +#define NFILE 100 // open files per system +#define NINODE 50 // maximum number of active i-nodes +#define NDEV 10 // maximum major device number +#define ROOTDEV 1 // device number of file system root disk +#define MAXARG 32 // max exec arguments +#define MAXOPBLOCKS 10 // max # of blocks any FS op writes +#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log +#define NBUF (MAXOPBLOCKS*3) // size of disk block cache +#define FSSIZE 1000 // size of file system in blocks +#define MAXCONSOLES 10 // Max number of consoles that can be open diff --git a/picirq.c b/picirq.c new file mode 100644 index 0000000..2abdc69 --- /dev/null +++ b/picirq.c @@ -0,0 +1,17 @@ +#include "types.h" +#include "x86.h" +#include "traps.h" + +// I/O Addresses of the two programmable interrupt controllers +#define IO_PIC1 0x20 // Master (IRQs 0-7) +#define IO_PIC2 0xA0 // Slave (IRQs 8-15) + +// Don't use the 8259A interrupt controllers. Xv6 assumes SMP hardware. +void picinit(void) { + // mask all interrupts + outb(IO_PIC1 + 1, 0xFF); + outb(IO_PIC2 + 1, 0xFF); +} + + + diff --git a/picirq.d b/picirq.d new file mode 100644 index 0000000..5233e7e --- /dev/null +++ b/picirq.d @@ -0,0 +1 @@ +picirq.o: picirq.c /usr/include/stdc-predef.h types.h x86.h traps.h diff --git a/picirq.o b/picirq.o new file mode 100644 index 0000000..2da8969 Binary files /dev/null and b/picirq.o differ diff --git a/pipe.c b/pipe.c new file mode 100644 index 0000000..579d7f5 --- /dev/null +++ b/pipe.c @@ -0,0 +1,122 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "mmu.h" +#include "proc.h" +#include "fs.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "file.h" + +#define PIPESIZE 512 + +struct pipe { + struct spinlock lock; + char data[PIPESIZE]; + uint nread; // number of bytes read + uint nwrite; // number of bytes written + int readopen; // read fd is still open + int writeopen; // write fd is still open +}; + +void cleanuppipealloc(struct pipe *p, struct file **f0, struct file **f1) { + if (p) { + kfree((char*)p); + } + if (*f0) { + fileclose(*f0); + } + if (*f1) { + fileclose(*f1); + } +} + +int pipealloc(struct file **f0, struct file **f1) { + struct pipe *p; + + p = 0; + *f0 = *f1 = 0; + if ((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) { + cleanuppipealloc(p, f0, f1); + return -1; + } + if ((p = (struct pipe*)kalloc()) == 0) { + cleanuppipealloc(p, f0, f1); + return -1; + } + p->readopen = 1; + p->writeopen = 1; + p->nwrite = 0; + p->nread = 0; + initlock(&p->lock, "pipe"); + (*f0)->type = FD_PIPE; + (*f0)->readable = 1; + (*f0)->writable = 0; + (*f0)->pipe = p; + (*f1)->type = FD_PIPE; + (*f1)->readable = 0; + (*f1)->writable = 1; + (*f1)->pipe = p; + return 0; +} + +void pipeclose(struct pipe *p, int writable) { + acquire(&p->lock); + if (writable) { + p->writeopen = 0; + wakeup(&p->nread); + } + else { + p->readopen = 0; + wakeup(&p->nwrite); + } + if (p->readopen == 0 && p->writeopen == 0) { + release(&p->lock); + kfree((char*)p); + } + else { + release(&p->lock); + } +} + +int pipewrite(struct pipe *p, char *addr, int n) { + int i; + + acquire(&p->lock); + for (i = 0; i < n; i++) { + while (p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full + if (p->readopen == 0 || myproc()->killed) { + release(&p->lock); + return -1; + } + wakeup(&p->nread); + sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep + } + p->data[p->nwrite++ % PIPESIZE] = addr[i]; + } + wakeup(&p->nread); //DOC: pipewrite-wakeup1 + release(&p->lock); + return n; +} + +int piperead(struct pipe *p, char *addr, int n) { + int i; + + acquire(&p->lock); + while (p->nread == p->nwrite && p->writeopen) { //DOC: pipe-empty + if (myproc()->killed) { + release(&p->lock); + return -1; + } + sleep(&p->nread, &p->lock); //DOC: piperead-sleep + } + for (i = 0; i < n; i++) { //DOC: piperead-copy + if (p->nread == p->nwrite) { + break; + } + addr[i] = p->data[p->nread++ % PIPESIZE]; + } + wakeup(&p->nwrite); //DOC: piperead-wakeup + release(&p->lock); + return i; +} diff --git a/pipe.d b/pipe.d new file mode 100644 index 0000000..3d0eac9 --- /dev/null +++ b/pipe.d @@ -0,0 +1,2 @@ +pipe.o: pipe.c /usr/include/stdc-predef.h types.h defs.h param.h mmu.h \ + proc.h fs.h spinlock.h sleeplock.h file.h diff --git a/pipe.o b/pipe.o new file mode 100644 index 0000000..d5dd977 Binary files /dev/null and b/pipe.o differ diff --git a/printf.c b/printf.c new file mode 100644 index 0000000..6f3b091 --- /dev/null +++ b/printf.c @@ -0,0 +1,91 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + static char digits[] = "0123456789ABCDEF"; + char buf[16]; + int i, neg; + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + } + else { + x = xx; + } + + i = 0; + do { + buf[i++] = digits[x % base]; + } + while ((x /= base) != 0); + if (neg) { + buf[i++] = '-'; + } + + while (--i >= 0) { + putc(fd, buf[i]); + } +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + } + else { + putc(fd, c); + } + } + else if (state == '%') { + if (c == 'd') { + printint(fd, *ap, 10, 1); + ap++; + } + else if (c == 'x' || c == 'p') { + printint(fd, *ap, 16, 0); + ap++; + } + else if (c == 's') { + s = (char*)*ap; + ap++; + if (s == 0) { + s = "(null)"; + } + while (*s != 0) { + putc(fd, *s); + s++; + } + } + else if (c == 'c') { + putc(fd, *ap); + ap++; + } + else if (c == '%') { + putc(fd, c); + } + else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + } + } +} diff --git a/printf.d b/printf.d new file mode 100644 index 0000000..ddd3a8d --- /dev/null +++ b/printf.d @@ -0,0 +1 @@ +printf.o: printf.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/printf.o b/printf.o new file mode 100644 index 0000000..940bfcd Binary files /dev/null and b/printf.o differ diff --git a/proc.c b/proc.c new file mode 100644 index 0000000..dc3ea65 --- /dev/null +++ b/proc.c @@ -0,0 +1,527 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "x86.h" +#include "proc.h" +#include "spinlock.h" + +struct { + struct spinlock lock; + struct proc proc[NPROC]; +} ptable; + +static struct proc *initproc; + +int nextpid = 1; +extern void forkret(void); +extern void trapret(void); + +static void wakeup1(void *chan); + +void pinit(void) { + initlock(&ptable.lock, "ptable"); +} + +// Must be called with interrupts disabled +int cpuid() { + return mycpu() - cpus; +} + +// Must be called with interrupts disabled to avoid the caller being +// rescheduled between reading lapicid and running through the loop. +struct cpu*mycpu(void) { + int apicid, i; + + if (readeflags() & FL_IF) { + panic("mycpu called with interrupts enabled\n"); + } + + apicid = lapicid(); + // APIC IDs are not guaranteed to be contiguous. Maybe we should have + // a reverse map, or reserve a register to store &cpus[i]. + for (i = 0; i < ncpu; ++i) { + if (cpus[i].apicid == apicid) { + return &cpus[i]; + } + } + panic("unknown apicid\n"); +} + +// Disable interrupts so that we are not rescheduled +// while reading proc from the cpu structure +struct proc*myproc(void) { + struct cpu *c; + struct proc *p; + pushcli(); + c = mycpu(); + p = c->proc; + popcli(); + return p; +} + +// Look in the process table for an UNUSED proc. +// If found, change state to EMBRYO and initialize +// state required to run in the kernel. +// Otherwise return 0. +static struct proc* allocproc(void) { + struct proc *p; + char *sp; + int found = 0; + + acquire(&ptable.lock); + + p = ptable.proc; + while (p < &ptable.proc[NPROC] && !found) { + if (p->state == UNUSED) { + found = 1; + } + else { + p++; + } + + } + if (!found) { + release(&ptable.lock); + return 0; + } + + p->state = EMBRYO; + p->pid = nextpid++; + + release(&ptable.lock); + + // Allocate kernel stack. + if ((p->kstack = kalloc()) == 0) { + p->state = UNUSED; + return 0; + } + sp = p->kstack + KSTACKSIZE; + + // Leave room for trap frame. + sp -= sizeof *p->tf; + p->tf = (struct trapframe*)sp; + + // Set up new context to start executing at forkret, + // which returns to trapret. + sp -= 4; + *(uint*)sp = (uint)trapret; + + sp -= sizeof *p->context; + p->context = (struct context*)sp; + memset(p->context, 0, sizeof *p->context); + p->context->eip = (uint)forkret; + + return p; +} + +// Set up first user process. +void userinit(void) { + struct proc *p; + extern char _binary_initcode_start[], _binary_initcode_size[]; + + p = allocproc(); + + initproc = p; + if ((p->pgdir = setupkvm()) == 0) { + panic("userinit: out of memory?"); + } + inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size); + p->sz = PGSIZE; + memset(p->tf, 0, sizeof(*p->tf)); + p->tf->cs = (SEG_UCODE << 3) | DPL_USER; + p->tf->ds = (SEG_UDATA << 3) | DPL_USER; + p->tf->es = p->tf->ds; + p->tf->ss = p->tf->ds; + p->tf->eflags = FL_IF; + p->tf->esp = PGSIZE; + p->tf->eip = 0; // beginning of initcode.S + + safestrcpy(p->name, "initcode", sizeof(p->name)); + p->cwd = namei("/"); + + // this assignment to p->state lets other cores + // run this process. the acquire forces the above + // writes to be visible, and the lock is also needed + // because the assignment might not be atomic. + acquire(&ptable.lock); + + p->state = RUNNABLE; + + release(&ptable.lock); +} + +// Grow current process's memory by n bytes. +// Return 0 on success, -1 on failure. +int growproc(int n) { + uint sz; + struct proc *curproc = myproc(); + + sz = curproc->sz; + if (n > 0) { + if ((sz = allocuvm(curproc->pgdir, sz, sz + n)) == 0) { + return -1; + } + } + else if (n < 0) { + if ((sz = deallocuvm(curproc->pgdir, sz, sz + n)) == 0) { + return -1; + } + } + curproc->sz = sz; + switchuvm(curproc); + return 0; +} + +// Create a new process copying p as the parent. +// Sets up stack to return as if from system call. +// Caller must set state of returned proc to RUNNABLE. +int fork(void) { + int i, pid; + struct proc *np; + struct proc *curproc = myproc(); + + // Allocate process. + if ((np = allocproc()) == 0) { + return -1; + } + + // Copy process state from proc. + if ((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0) { + kfree(np->kstack); + np->kstack = 0; + np->state = UNUSED; + return -1; + } + np->sz = curproc->sz; + np->parent = curproc; + *np->tf = *curproc->tf; + + // Clear %eax so that fork returns 0 in the child. + np->tf->eax = 0; + + for (i = 0; i < NOFILE; i++) { + if (curproc->ofile[i]) { + np->ofile[i] = filedup(curproc->ofile[i]); + } + } + np->cwd = idup(curproc->cwd); + + safestrcpy(np->name, curproc->name, sizeof(curproc->name)); + + pid = np->pid; + + acquire(&ptable.lock); + + np->state = RUNNABLE; + + release(&ptable.lock); + + return pid; +} + +// Exit the current process. Does not return. +// An exited process remains in the zombie state +// until its parent calls wait() to find out it exited. +void exit(void) { + struct proc *curproc = myproc(); + struct proc *p; + int fd; + + if (curproc == initproc) { + panic("init exiting"); + } + + // Close all open files. + for (fd = 0; fd < NOFILE; fd++) { + if (curproc->ofile[fd]) { + fileclose(curproc->ofile[fd]); + curproc->ofile[fd] = 0; + } + } + + begin_op(); + iput(curproc->cwd); + end_op(); + curproc->cwd = 0; + + acquire(&ptable.lock); + + // Parent might be sleeping in wait(). + wakeup1(curproc->parent); + + // Pass abandoned children to init. + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { + if (p->parent == curproc) { + p->parent = initproc; + if (p->state == ZOMBIE) { + wakeup1(initproc); + } + } + } + + // Jump into the scheduler, never to return. + curproc->state = ZOMBIE; + sched(); + panic("zombie exit"); +} + +// Wait for a child process to exit and return its pid. +// Return -1 if this process has no children. +int wait(void) { + struct proc *p; + int havekids, pid; + struct proc *curproc = myproc(); + + acquire(&ptable.lock); + for (;;) { + // Scan through table looking for exited children. + havekids = 0; + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { + if (p->parent != curproc) { + continue; + } + havekids = 1; + if (p->state == ZOMBIE) { + // Found one. + pid = p->pid; + kfree(p->kstack); + p->kstack = 0; + freevm(p->pgdir); + p->pid = 0; + p->parent = 0; + p->name[0] = 0; + p->killed = 0; + p->state = UNUSED; + release(&ptable.lock); + return pid; + } + } + + // No point waiting if we don't have any children. + if (!havekids || curproc->killed) { + release(&ptable.lock); + return -1; + } + + // Wait for children to exit. (See wakeup1 call in proc_exit.) + sleep(curproc, &ptable.lock); //DOC: wait-sleep + } +} + +// Per-CPU process scheduler. +// Each CPU calls scheduler() after setting itself up. +// Scheduler never returns. It loops, doing: +// - choose a process to run +// - swtch to start running that process +// - eventually that process transfers control +// via swtch back to the scheduler. +void scheduler(void) { + struct proc *p; + struct cpu *c = mycpu(); + c->proc = 0; + + for (;;) { + // Enable interrupts on this processor. + sti(); + + // Loop over process table looking for process to run. + acquire(&ptable.lock); + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { + if (p->state != RUNNABLE) { + continue; + } + + // Switch to chosen process. It is the process's job + // to release ptable.lock and then reacquire it + // before jumping back to us. + c->proc = p; + switchuvm(p); + p->state = RUNNING; + + swtch(&(c->scheduler), p->context); + switchkvm(); + + // Process is done running for now. + // It should have changed its p->state before coming back. + c->proc = 0; + } + release(&ptable.lock); + + } +} + +// Enter scheduler. Must hold only ptable.lock +// and have changed proc->state. Saves and restores +// intena because intena is a property of this +// kernel thread, not this CPU. It should +// be proc->intena and proc->ncli, but that would +// break in the few places where a lock is held but +// there's no process. +void sched(void) { + int intena; + struct proc *p = myproc(); + + if (!holding(&ptable.lock)) { + panic("sched ptable.lock"); + } + if (mycpu()->ncli != 1) { + panic("sched locks"); + } + if (p->state == RUNNING) { + panic("sched running"); + } + if (readeflags() & FL_IF) { + panic("sched interruptible"); + } + intena = mycpu()->intena; + swtch(&p->context, mycpu()->scheduler); + mycpu()->intena = intena; +} + +// Give up the CPU for one scheduling round. +void yield(void) { + acquire(&ptable.lock); //DOC: yieldlock + myproc()->state = RUNNABLE; + sched(); + release(&ptable.lock); +} + +// A fork child's very first scheduling by scheduler() +// will swtch here. "Return" to user space. +void forkret(void) { + static int first = 1; + // Still holding ptable.lock from scheduler. + release(&ptable.lock); + + if (first) { + // Some initialization functions must be run in the context + // of a regular process (e.g., they call sleep), and thus cannot + // be run from main(). + first = 0; + iinit(ROOTDEV); + initlog(ROOTDEV); + } + + // Return to "caller", actually trapret (see allocproc). +} + +// Atomically release lock and sleep on chan. +// Reacquires lock when awakened. +void sleep(void *chan, struct spinlock *lk) { + struct proc *p = myproc(); + + if (p == 0) { + panic("sleep"); + } + + if (lk == 0) { + panic("sleep without lk"); + } + + // Must acquire ptable.lock in order to + // change p->state and then call sched. + // Once we hold ptable.lock, we can be + // guaranteed that we won't miss any wakeup + // (wakeup runs with ptable.lock locked), + // so it's okay to release lk. + if (lk != &ptable.lock) { //DOC: sleeplock0 + acquire(&ptable.lock); //DOC: sleeplock1 + release(lk); + } + // Go to sleep. + p->chan = chan; + p->state = SLEEPING; + + sched(); + + // Tidy up. + p->chan = 0; + + // Reacquire original lock. + if (lk != &ptable.lock) { //DOC: sleeplock2 + release(&ptable.lock); + acquire(lk); + } +} + + +// Wake up all processes sleeping on chan. +// The ptable lock must be held. +static void wakeup1(void *chan) { + struct proc *p; + + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { + if (p->state == SLEEPING && p->chan == chan) { + p->state = RUNNABLE; + } + } +} + +// Wake up all processes sleeping on chan. +void wakeup(void *chan) { + acquire(&ptable.lock); + wakeup1(chan); + release(&ptable.lock); +} + +// Kill the process with the given pid. +// Process won't exit until it returns +// to user space (see trap in trap.c). +int kill(int pid) { + struct proc *p; + + acquire(&ptable.lock); + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { + if (p->pid == pid) { + p->killed = 1; + // Wake process from sleep if necessary. + if (p->state == SLEEPING) { + p->state = RUNNABLE; + } + release(&ptable.lock); + return 0; + } + } + release(&ptable.lock); + return -1; +} + +// Print a process listing to console. For debugging. +// Runs when user types ^P on console. +// No lock to avoid wedging a stuck machine further. +void procdump(void) { + static char *states[] = { + [UNUSED] "unused", + [EMBRYO] "embryo", + [SLEEPING] "sleep ", + [RUNNABLE] "runble", + [RUNNING] "run ", + [ZOMBIE] "zombie" + }; + int i; + struct proc *p; + char *state; + uint pc[10]; + + for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) { + if (p->state == UNUSED) { + continue; + } + if (p->state >= 0 && p->state < NELEM(states) && states[p->state]) { + state = states[p->state]; + } + else { + state = "???"; + } + cprintf("%d %s %s", p->pid, state, p->name); + if (p->state == SLEEPING) { + getcallerpcs((uint*)p->context->ebp + 2, pc); + for (i = 0; i < 10 && pc[i] != 0; i++) { + cprintf(" %p", pc[i]); + } + } + cprintf("\n"); + } +} diff --git a/proc.d b/proc.d new file mode 100644 index 0000000..9396fef --- /dev/null +++ b/proc.d @@ -0,0 +1,2 @@ +proc.o: proc.c /usr/include/stdc-predef.h types.h defs.h param.h \ + memlayout.h mmu.h x86.h proc.h spinlock.h diff --git a/proc.h b/proc.h new file mode 100644 index 0000000..124590e --- /dev/null +++ b/proc.h @@ -0,0 +1,57 @@ +// Per-CPU state +struct cpu { + uchar apicid; // Local APIC ID + struct context *scheduler; // swtch() here to enter scheduler + struct taskstate ts; // Used by x86 to find stack for interrupt + struct segdesc gdt[NSEGS]; // x86 global descriptor table + volatile uint started; // Has the CPU started? + int ncli; // Depth of pushcli nesting. + int intena; // Were interrupts enabled before pushcli? + struct proc *proc; // The process running on this cpu or null +}; + +extern struct cpu cpus[NCPU]; +extern int ncpu; + +// Saved registers for kernel context switches. +// Don't need to save all the segment registers (%cs, etc), +// because they are constant across kernel contexts. +// Don't need to save %eax, %ecx, %edx, because the +// x86 convention is that the caller has saved them. +// Contexts are stored at the bottom of the stack they +// describe; the stack pointer is the address of the context. +// The layout of the context matches the layout of the stack in swtch.S +// at the "Switch stacks" comment. Switch doesn't save eip explicitly, +// but it is on the stack and allocproc() manipulates it. +struct context { + uint edi; + uint esi; + uint ebx; + uint ebp; + uint eip; +}; + +enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; + +// Per-process state +struct proc { + uint sz; // Size of process memory (bytes) + pde_t* pgdir; // Page table + char *kstack; // Bottom of kernel stack for this process + enum procstate state; // Process state + int pid; // Process ID + struct proc *parent; // Parent process + struct trapframe *tf; // Trap frame for current syscall + struct context *context; // swtch() here to run process + void *chan; // If non-zero, sleeping on chan + int killed; // If non-zero, have been killed + struct file *ofile[NOFILE]; // Open files + struct inode *cwd; // Current directory + char name[16]; // Process name (debugging) +}; + +// Process memory is laid out contiguously, low addresses first: +// text +// original data and bss +// fixed-size stack +// expandable heap diff --git a/proc.o b/proc.o new file mode 100644 index 0000000..23afe49 Binary files /dev/null and b/proc.o differ diff --git a/rm.asm b/rm.asm new file mode 100644 index 0000000..1ed1103 --- /dev/null +++ b/rm.asm @@ -0,0 +1,1190 @@ + +_rm: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: bf 01 00 00 00 mov $0x1,%edi + 13: 56 push %esi + 14: 53 push %ebx + 15: 51 push %ecx + 16: 83 ec 08 sub $0x8,%esp + 19: 8b 59 04 mov 0x4(%ecx),%ebx + 1c: 8b 31 mov (%ecx),%esi + 1e: 83 c3 04 add $0x4,%ebx + int i; + + if (argc < 2) { + 21: 83 fe 01 cmp $0x1,%esi + 24: 7e 3e jle 64 + 26: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2d: 8d 76 00 lea 0x0(%esi),%esi + printf(2, "Usage: rm files...\n"); + exit(); + } + + for (i = 1; i < argc; i++) { + if (unlink(argv[i]) < 0) { + 30: 83 ec 0c sub $0xc,%esp + 33: ff 33 push (%ebx) + 35: e8 19 03 00 00 call 353 + 3a: 83 c4 10 add $0x10,%esp + 3d: 85 c0 test %eax,%eax + 3f: 78 0f js 50 + for (i = 1; i < argc; i++) { + 41: 83 c7 01 add $0x1,%edi + 44: 83 c3 04 add $0x4,%ebx + 47: 39 fe cmp %edi,%esi + 49: 75 e5 jne 30 + printf(2, "rm: %s failed to delete\n", argv[i]); + break; + } + } + + exit(); + 4b: e8 83 02 00 00 call 2d3 + printf(2, "rm: %s failed to delete\n", argv[i]); + 50: 50 push %eax + 51: ff 33 push (%ebx) + 53: 68 7c 07 00 00 push $0x77c + 58: 6a 02 push $0x2 + 5a: e8 e1 03 00 00 call 440 + break; + 5f: 83 c4 10 add $0x10,%esp + 62: eb e7 jmp 4b + printf(2, "Usage: rm files...\n"); + 64: 52 push %edx + 65: 52 push %edx + 66: 68 68 07 00 00 push $0x768 + 6b: 6a 02 push $0x2 + 6d: e8 ce 03 00 00 call 440 + exit(); + 72: e8 5c 02 00 00 call 2d3 + 77: 66 90 xchg %ax,%ax + 79: 66 90 xchg %ax,%ax + 7b: 66 90 xchg %ax,%ax + 7d: 66 90 xchg %ax,%ax + 7f: 90 nop + +00000080 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 80: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 81: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 83: 89 e5 mov %esp,%ebp + 85: 53 push %ebx + 86: 8b 4d 08 mov 0x8(%ebp),%ecx + 89: 8b 5d 0c mov 0xc(%ebp),%ebx + 8c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 90: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 94: 88 14 01 mov %dl,(%ecx,%eax,1) + 97: 83 c0 01 add $0x1,%eax + 9a: 84 d2 test %dl,%dl + 9c: 75 f2 jne 90 + ; + } + return os; +} + 9e: 8b 5d fc mov -0x4(%ebp),%ebx + a1: 89 c8 mov %ecx,%eax + a3: c9 leave + a4: c3 ret + a5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000000b0 : + +int strcmp(const char *p, const char *q) { + b0: 55 push %ebp + b1: 89 e5 mov %esp,%ebp + b3: 53 push %ebx + b4: 8b 55 08 mov 0x8(%ebp),%edx + b7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + ba: 0f b6 02 movzbl (%edx),%eax + bd: 84 c0 test %al,%al + bf: 75 17 jne d8 + c1: eb 3a jmp fd + c3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + c7: 90 nop + c8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + cc: 83 c2 01 add $0x1,%edx + cf: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + d2: 84 c0 test %al,%al + d4: 74 1a je f0 + p++, q++; + d6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + d8: 0f b6 19 movzbl (%ecx),%ebx + db: 38 c3 cmp %al,%bl + dd: 74 e9 je c8 + } + return (uchar) * p - (uchar) * q; + df: 29 d8 sub %ebx,%eax +} + e1: 8b 5d fc mov -0x4(%ebp),%ebx + e4: c9 leave + e5: c3 ret + e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + ed: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + f0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + f4: 31 c0 xor %eax,%eax + f6: 29 d8 sub %ebx,%eax +} + f8: 8b 5d fc mov -0x4(%ebp),%ebx + fb: c9 leave + fc: c3 ret + return (uchar) * p - (uchar) * q; + fd: 0f b6 19 movzbl (%ecx),%ebx + 100: 31 c0 xor %eax,%eax + 102: eb db jmp df + 104: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 10b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 10f: 90 nop + +00000110 : + +uint strlen(const char *s) { + 110: 55 push %ebp + 111: 89 e5 mov %esp,%ebp + 113: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 116: 80 3a 00 cmpb $0x0,(%edx) + 119: 74 15 je 130 + 11b: 31 c0 xor %eax,%eax + 11d: 8d 76 00 lea 0x0(%esi),%esi + 120: 83 c0 01 add $0x1,%eax + 123: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 127: 89 c1 mov %eax,%ecx + 129: 75 f5 jne 120 + ; + } + return n; +} + 12b: 89 c8 mov %ecx,%eax + 12d: 5d pop %ebp + 12e: c3 ret + 12f: 90 nop + for (n = 0; s[n]; n++) { + 130: 31 c9 xor %ecx,%ecx +} + 132: 5d pop %ebp + 133: 89 c8 mov %ecx,%eax + 135: c3 ret + 136: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 13d: 8d 76 00 lea 0x0(%esi),%esi + +00000140 : + +void* memset(void *dst, int c, uint n) { + 140: 55 push %ebp + 141: 89 e5 mov %esp,%ebp + 143: 57 push %edi + 144: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 147: 8b 4d 10 mov 0x10(%ebp),%ecx + 14a: 8b 45 0c mov 0xc(%ebp),%eax + 14d: 89 d7 mov %edx,%edi + 14f: fc cld + 150: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 152: 8b 7d fc mov -0x4(%ebp),%edi + 155: 89 d0 mov %edx,%eax + 157: c9 leave + 158: c3 ret + 159: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000160 : + +char* strchr(const char *s, char c) { + 160: 55 push %ebp + 161: 89 e5 mov %esp,%ebp + 163: 8b 45 08 mov 0x8(%ebp),%eax + 166: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 16a: 0f b6 10 movzbl (%eax),%edx + 16d: 84 d2 test %dl,%dl + 16f: 75 12 jne 183 + 171: eb 1d jmp 190 + 173: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 177: 90 nop + 178: 0f b6 50 01 movzbl 0x1(%eax),%edx + 17c: 83 c0 01 add $0x1,%eax + 17f: 84 d2 test %dl,%dl + 181: 74 0d je 190 + if (*s == c) { + 183: 38 d1 cmp %dl,%cl + 185: 75 f1 jne 178 + return (char*)s; + } + } + return 0; +} + 187: 5d pop %ebp + 188: c3 ret + 189: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 190: 31 c0 xor %eax,%eax +} + 192: 5d pop %ebp + 193: c3 ret + 194: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 19b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 19f: 90 nop + +000001a0 : + +char* gets(char *buf, int max) { + 1a0: 55 push %ebp + 1a1: 89 e5 mov %esp,%ebp + 1a3: 57 push %edi + 1a4: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 1a5: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 1a8: 53 push %ebx + for (i = 0; i + 1 < max;) { + 1a9: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 1ab: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 1ae: eb 27 jmp 1d7 + cc = read(0, &c, 1); + 1b0: 83 ec 04 sub $0x4,%esp + 1b3: 6a 01 push $0x1 + 1b5: 57 push %edi + 1b6: 6a 00 push $0x0 + 1b8: e8 2e 01 00 00 call 2eb + if (cc < 1) { + 1bd: 83 c4 10 add $0x10,%esp + 1c0: 85 c0 test %eax,%eax + 1c2: 7e 1d jle 1e1 + break; + } + buf[i++] = c; + 1c4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 1c8: 8b 55 08 mov 0x8(%ebp),%edx + 1cb: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 1cf: 3c 0a cmp $0xa,%al + 1d1: 74 1d je 1f0 + 1d3: 3c 0d cmp $0xd,%al + 1d5: 74 19 je 1f0 + for (i = 0; i + 1 < max;) { + 1d7: 89 de mov %ebx,%esi + 1d9: 83 c3 01 add $0x1,%ebx + 1dc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1df: 7c cf jl 1b0 + break; + } + } + buf[i] = '\0'; + 1e1: 8b 45 08 mov 0x8(%ebp),%eax + 1e4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1e8: 8d 65 f4 lea -0xc(%ebp),%esp + 1eb: 5b pop %ebx + 1ec: 5e pop %esi + 1ed: 5f pop %edi + 1ee: 5d pop %ebp + 1ef: c3 ret + buf[i] = '\0'; + 1f0: 8b 45 08 mov 0x8(%ebp),%eax + 1f3: 89 de mov %ebx,%esi + 1f5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 1f9: 8d 65 f4 lea -0xc(%ebp),%esp + 1fc: 5b pop %ebx + 1fd: 5e pop %esi + 1fe: 5f pop %edi + 1ff: 5d pop %ebp + 200: c3 ret + 201: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 208: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 20f: 90 nop + +00000210 : + +int stat(const char *n, struct stat *st) { + 210: 55 push %ebp + 211: 89 e5 mov %esp,%ebp + 213: 56 push %esi + 214: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 215: 83 ec 08 sub $0x8,%esp + 218: 6a 00 push $0x0 + 21a: ff 75 08 push 0x8(%ebp) + 21d: e8 19 01 00 00 call 33b + if (fd < 0) { + 222: 83 c4 10 add $0x10,%esp + 225: 85 c0 test %eax,%eax + 227: 78 27 js 250 + return -1; + } + r = fstat(fd, st); + 229: 83 ec 08 sub $0x8,%esp + 22c: ff 75 0c push 0xc(%ebp) + 22f: 89 c3 mov %eax,%ebx + 231: 50 push %eax + 232: e8 cc 00 00 00 call 303 + close(fd); + 237: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 23a: 89 c6 mov %eax,%esi + close(fd); + 23c: e8 2a 01 00 00 call 36b + return r; + 241: 83 c4 10 add $0x10,%esp +} + 244: 8d 65 f8 lea -0x8(%ebp),%esp + 247: 89 f0 mov %esi,%eax + 249: 5b pop %ebx + 24a: 5e pop %esi + 24b: 5d pop %ebp + 24c: c3 ret + 24d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 250: be ff ff ff ff mov $0xffffffff,%esi + 255: eb ed jmp 244 + 257: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 25e: 66 90 xchg %ax,%ax + +00000260 : + +int atoi(const char *s) { + 260: 55 push %ebp + 261: 89 e5 mov %esp,%ebp + 263: 53 push %ebx + 264: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 267: 0f be 02 movsbl (%edx),%eax + 26a: 8d 48 d0 lea -0x30(%eax),%ecx + 26d: 80 f9 09 cmp $0x9,%cl + n = 0; + 270: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 275: 77 1e ja 295 + 277: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 27e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 280: 83 c2 01 add $0x1,%edx + 283: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 286: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 28a: 0f be 02 movsbl (%edx),%eax + 28d: 8d 58 d0 lea -0x30(%eax),%ebx + 290: 80 fb 09 cmp $0x9,%bl + 293: 76 eb jbe 280 + } + return n; +} + 295: 8b 5d fc mov -0x4(%ebp),%ebx + 298: 89 c8 mov %ecx,%eax + 29a: c9 leave + 29b: c3 ret + 29c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000002a0 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 2a0: 55 push %ebp + 2a1: 89 e5 mov %esp,%ebp + 2a3: 57 push %edi + 2a4: 8b 45 10 mov 0x10(%ebp),%eax + 2a7: 8b 55 08 mov 0x8(%ebp),%edx + 2aa: 56 push %esi + 2ab: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 2ae: 85 c0 test %eax,%eax + 2b0: 7e 13 jle 2c5 + 2b2: 01 d0 add %edx,%eax + dst = vdst; + 2b4: 89 d7 mov %edx,%edi + 2b6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2bd: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 2c0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 2c1: 39 f8 cmp %edi,%eax + 2c3: 75 fb jne 2c0 + } + return vdst; +} + 2c5: 5e pop %esi + 2c6: 89 d0 mov %edx,%eax + 2c8: 5f pop %edi + 2c9: 5d pop %ebp + 2ca: c3 ret + +000002cb : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 2cb: b8 01 00 00 00 mov $0x1,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(exit) + 2d3: b8 02 00 00 00 mov $0x2,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(wait) + 2db: b8 03 00 00 00 mov $0x3,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(pipe) + 2e3: b8 04 00 00 00 mov $0x4,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(read) + 2eb: b8 05 00 00 00 mov $0x5,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(kill) + 2f3: b8 06 00 00 00 mov $0x6,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(exec) + 2fb: b8 07 00 00 00 mov $0x7,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(fstat) + 303: b8 08 00 00 00 mov $0x8,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(chdir) + 30b: b8 09 00 00 00 mov $0x9,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(dup) + 313: b8 0a 00 00 00 mov $0xa,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(getpid) + 31b: b8 0b 00 00 00 mov $0xb,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(sbrk) + 323: b8 0c 00 00 00 mov $0xc,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(sleep) + 32b: b8 0d 00 00 00 mov $0xd,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(uptime) + 333: b8 0e 00 00 00 mov $0xe,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(open) + 33b: b8 0f 00 00 00 mov $0xf,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(write) + 343: b8 10 00 00 00 mov $0x10,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(mknod) + 34b: b8 11 00 00 00 mov $0x11,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(unlink) + 353: b8 12 00 00 00 mov $0x12,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(link) + 35b: b8 13 00 00 00 mov $0x13,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(mkdir) + 363: b8 14 00 00 00 mov $0x14,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + +0000036b : +SYSCALL(close) + 36b: b8 15 00 00 00 mov $0x15,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(getch) + 373: b8 16 00 00 00 mov $0x16,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + +0000037b : +SYSCALL(greeting) + 37b: b8 17 00 00 00 mov $0x17,%eax + 380: cd 40 int $0x40 + 382: c3 ret + +00000383 : +SYSCALL(shutdown) + 383: b8 18 00 00 00 mov $0x18,%eax + 388: cd 40 int $0x40 + 38a: c3 ret + 38b: 66 90 xchg %ax,%ax + 38d: 66 90 xchg %ax,%ax + 38f: 90 nop + +00000390 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 390: 55 push %ebp + 391: 89 e5 mov %esp,%ebp + 393: 57 push %edi + 394: 56 push %esi + 395: 53 push %ebx + 396: 83 ec 3c sub $0x3c,%esp + 399: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 39c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 39e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 3a1: 85 d2 test %edx,%edx + 3a3: 0f 89 7f 00 00 00 jns 428 + 3a9: f6 45 08 01 testb $0x1,0x8(%ebp) + 3ad: 74 79 je 428 + neg = 1; + 3af: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 3b6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 3b8: 31 db xor %ebx,%ebx + 3ba: 8d 75 d7 lea -0x29(%ebp),%esi + 3bd: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 3c0: 89 c8 mov %ecx,%eax + 3c2: 31 d2 xor %edx,%edx + 3c4: 89 cf mov %ecx,%edi + 3c6: f7 75 c4 divl -0x3c(%ebp) + 3c9: 0f b6 92 f4 07 00 00 movzbl 0x7f4(%edx),%edx + 3d0: 89 45 c0 mov %eax,-0x40(%ebp) + 3d3: 89 d8 mov %ebx,%eax + 3d5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3d8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3db: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3de: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3e1: 76 dd jbe 3c0 + if (neg) { + 3e3: 8b 4d bc mov -0x44(%ebp),%ecx + 3e6: 85 c9 test %ecx,%ecx + 3e8: 74 0c je 3f6 + buf[i++] = '-'; + 3ea: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3ef: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 3f1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 3f6: 8b 7d b8 mov -0x48(%ebp),%edi + 3f9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 3fd: eb 07 jmp 406 + 3ff: 90 nop + putc(fd, buf[i]); + 400: 0f b6 13 movzbl (%ebx),%edx + 403: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 406: 83 ec 04 sub $0x4,%esp + 409: 88 55 d7 mov %dl,-0x29(%ebp) + 40c: 6a 01 push $0x1 + 40e: 56 push %esi + 40f: 57 push %edi + 410: e8 2e ff ff ff call 343 + while (--i >= 0) { + 415: 83 c4 10 add $0x10,%esp + 418: 39 de cmp %ebx,%esi + 41a: 75 e4 jne 400 + } +} + 41c: 8d 65 f4 lea -0xc(%ebp),%esp + 41f: 5b pop %ebx + 420: 5e pop %esi + 421: 5f pop %edi + 422: 5d pop %ebp + 423: c3 ret + 424: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 428: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 42f: eb 87 jmp 3b8 + 431: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 438: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 43f: 90 nop + +00000440 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 440: 55 push %ebp + 441: 89 e5 mov %esp,%ebp + 443: 57 push %edi + 444: 56 push %esi + 445: 53 push %ebx + 446: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 449: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 44c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 44f: 0f b6 13 movzbl (%ebx),%edx + 452: 84 d2 test %dl,%dl + 454: 74 6a je 4c0 + ap = (uint*)(void*)&fmt + 1; + 456: 8d 45 10 lea 0x10(%ebp),%eax + 459: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 45c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 45f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 461: 89 45 d0 mov %eax,-0x30(%ebp) + 464: eb 36 jmp 49c + 466: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 46d: 8d 76 00 lea 0x0(%esi),%esi + 470: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 473: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 478: 83 f8 25 cmp $0x25,%eax + 47b: 74 15 je 492 + write(fd, &c, 1); + 47d: 83 ec 04 sub $0x4,%esp + 480: 88 55 e7 mov %dl,-0x19(%ebp) + 483: 6a 01 push $0x1 + 485: 57 push %edi + 486: 56 push %esi + 487: e8 b7 fe ff ff call 343 + 48c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 48f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 492: 0f b6 13 movzbl (%ebx),%edx + 495: 83 c3 01 add $0x1,%ebx + 498: 84 d2 test %dl,%dl + 49a: 74 24 je 4c0 + c = fmt[i] & 0xff; + 49c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 49f: 85 c9 test %ecx,%ecx + 4a1: 74 cd je 470 + } + } + else if (state == '%') { + 4a3: 83 f9 25 cmp $0x25,%ecx + 4a6: 75 ea jne 492 + if (c == 'd') { + 4a8: 83 f8 25 cmp $0x25,%eax + 4ab: 0f 84 07 01 00 00 je 5b8 + 4b1: 83 e8 63 sub $0x63,%eax + 4b4: 83 f8 15 cmp $0x15,%eax + 4b7: 77 17 ja 4d0 + 4b9: ff 24 85 9c 07 00 00 jmp *0x79c(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 4c0: 8d 65 f4 lea -0xc(%ebp),%esp + 4c3: 5b pop %ebx + 4c4: 5e pop %esi + 4c5: 5f pop %edi + 4c6: 5d pop %ebp + 4c7: c3 ret + 4c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4cf: 90 nop + write(fd, &c, 1); + 4d0: 83 ec 04 sub $0x4,%esp + 4d3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4d6: 6a 01 push $0x1 + 4d8: 57 push %edi + 4d9: 56 push %esi + 4da: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4de: e8 60 fe ff ff call 343 + putc(fd, c); + 4e3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4e7: 83 c4 0c add $0xc,%esp + 4ea: 88 55 e7 mov %dl,-0x19(%ebp) + 4ed: 6a 01 push $0x1 + 4ef: 57 push %edi + 4f0: 56 push %esi + 4f1: e8 4d fe ff ff call 343 + putc(fd, c); + 4f6: 83 c4 10 add $0x10,%esp + state = 0; + 4f9: 31 c9 xor %ecx,%ecx + 4fb: eb 95 jmp 492 + 4fd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 500: 83 ec 0c sub $0xc,%esp + 503: b9 10 00 00 00 mov $0x10,%ecx + 508: 6a 00 push $0x0 + 50a: 8b 45 d0 mov -0x30(%ebp),%eax + 50d: 8b 10 mov (%eax),%edx + 50f: 89 f0 mov %esi,%eax + 511: e8 7a fe ff ff call 390 + ap++; + 516: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 51a: 83 c4 10 add $0x10,%esp + state = 0; + 51d: 31 c9 xor %ecx,%ecx + 51f: e9 6e ff ff ff jmp 492 + 524: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 528: 8b 45 d0 mov -0x30(%ebp),%eax + 52b: 8b 10 mov (%eax),%edx + ap++; + 52d: 83 c0 04 add $0x4,%eax + 530: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 533: 85 d2 test %edx,%edx + 535: 0f 84 8d 00 00 00 je 5c8 + while (*s != 0) { + 53b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 53e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 540: 84 c0 test %al,%al + 542: 0f 84 4a ff ff ff je 492 + 548: 89 5d d4 mov %ebx,-0x2c(%ebp) + 54b: 89 d3 mov %edx,%ebx + 54d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 550: 83 ec 04 sub $0x4,%esp + s++; + 553: 83 c3 01 add $0x1,%ebx + 556: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 559: 6a 01 push $0x1 + 55b: 57 push %edi + 55c: 56 push %esi + 55d: e8 e1 fd ff ff call 343 + while (*s != 0) { + 562: 0f b6 03 movzbl (%ebx),%eax + 565: 83 c4 10 add $0x10,%esp + 568: 84 c0 test %al,%al + 56a: 75 e4 jne 550 + state = 0; + 56c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 56f: 31 c9 xor %ecx,%ecx + 571: e9 1c ff ff ff jmp 492 + 576: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 57d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 580: 83 ec 0c sub $0xc,%esp + 583: b9 0a 00 00 00 mov $0xa,%ecx + 588: 6a 01 push $0x1 + 58a: e9 7b ff ff ff jmp 50a + 58f: 90 nop + putc(fd, *ap); + 590: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 593: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 596: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 598: 6a 01 push $0x1 + 59a: 57 push %edi + 59b: 56 push %esi + putc(fd, *ap); + 59c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 59f: e8 9f fd ff ff call 343 + ap++; + 5a4: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 5a8: 83 c4 10 add $0x10,%esp + state = 0; + 5ab: 31 c9 xor %ecx,%ecx + 5ad: e9 e0 fe ff ff jmp 492 + 5b2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 5b8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 5bb: 83 ec 04 sub $0x4,%esp + 5be: e9 2a ff ff ff jmp 4ed + 5c3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 5c7: 90 nop + s = "(null)"; + 5c8: ba 95 07 00 00 mov $0x795,%edx + while (*s != 0) { + 5cd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5d0: b8 28 00 00 00 mov $0x28,%eax + 5d5: 89 d3 mov %edx,%ebx + 5d7: e9 74 ff ff ff jmp 550 + 5dc: 66 90 xchg %ax,%ax + 5de: 66 90 xchg %ax,%ax + +000005e0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5e0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5e1: a1 ac 0a 00 00 mov 0xaac,%eax +void free(void *ap) { + 5e6: 89 e5 mov %esp,%ebp + 5e8: 57 push %edi + 5e9: 56 push %esi + 5ea: 53 push %ebx + 5eb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5ee: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5f8: 89 c2 mov %eax,%edx + 5fa: 8b 00 mov (%eax),%eax + 5fc: 39 ca cmp %ecx,%edx + 5fe: 73 30 jae 630 + 600: 39 c1 cmp %eax,%ecx + 602: 72 04 jb 608 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 604: 39 c2 cmp %eax,%edx + 606: 72 f0 jb 5f8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 608: 8b 73 fc mov -0x4(%ebx),%esi + 60b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 60e: 39 f8 cmp %edi,%eax + 610: 74 30 je 642 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 612: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 615: 8b 42 04 mov 0x4(%edx),%eax + 618: 8d 34 c2 lea (%edx,%eax,8),%esi + 61b: 39 f1 cmp %esi,%ecx + 61d: 74 3a je 659 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 61f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 621: 5b pop %ebx + freep = p; + 622: 89 15 ac 0a 00 00 mov %edx,0xaac +} + 628: 5e pop %esi + 629: 5f pop %edi + 62a: 5d pop %ebp + 62b: c3 ret + 62c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 630: 39 c2 cmp %eax,%edx + 632: 72 c4 jb 5f8 + 634: 39 c1 cmp %eax,%ecx + 636: 73 c0 jae 5f8 + if (bp + bp->s.size == p->s.ptr) { + 638: 8b 73 fc mov -0x4(%ebx),%esi + 63b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 63e: 39 f8 cmp %edi,%eax + 640: 75 d0 jne 612 + bp->s.size += p->s.ptr->s.size; + 642: 03 70 04 add 0x4(%eax),%esi + 645: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 648: 8b 02 mov (%edx),%eax + 64a: 8b 00 mov (%eax),%eax + 64c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 64f: 8b 42 04 mov 0x4(%edx),%eax + 652: 8d 34 c2 lea (%edx,%eax,8),%esi + 655: 39 f1 cmp %esi,%ecx + 657: 75 c6 jne 61f + p->s.size += bp->s.size; + 659: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 65c: 89 15 ac 0a 00 00 mov %edx,0xaac + p->s.size += bp->s.size; + 662: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 665: 8b 4b f8 mov -0x8(%ebx),%ecx + 668: 89 0a mov %ecx,(%edx) +} + 66a: 5b pop %ebx + 66b: 5e pop %esi + 66c: 5f pop %edi + 66d: 5d pop %ebp + 66e: c3 ret + 66f: 90 nop + +00000670 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 670: 55 push %ebp + 671: 89 e5 mov %esp,%ebp + 673: 57 push %edi + 674: 56 push %esi + 675: 53 push %ebx + 676: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 679: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 67c: 8b 3d ac 0a 00 00 mov 0xaac,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 682: 8d 70 07 lea 0x7(%eax),%esi + 685: c1 ee 03 shr $0x3,%esi + 688: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 68b: 85 ff test %edi,%edi + 68d: 0f 84 9d 00 00 00 je 730 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 693: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 695: 8b 4a 04 mov 0x4(%edx),%ecx + 698: 39 f1 cmp %esi,%ecx + 69a: 73 6a jae 706 + 69c: bb 00 10 00 00 mov $0x1000,%ebx + 6a1: 39 de cmp %ebx,%esi + 6a3: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 6a6: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 6ad: 89 45 e4 mov %eax,-0x1c(%ebp) + 6b0: eb 17 jmp 6c9 + 6b2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6b8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 6ba: 8b 48 04 mov 0x4(%eax),%ecx + 6bd: 39 f1 cmp %esi,%ecx + 6bf: 73 4f jae 710 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 6c1: 8b 3d ac 0a 00 00 mov 0xaac,%edi + 6c7: 89 c2 mov %eax,%edx + 6c9: 39 d7 cmp %edx,%edi + 6cb: 75 eb jne 6b8 + p = sbrk(nu * sizeof(Header)); + 6cd: 83 ec 0c sub $0xc,%esp + 6d0: ff 75 e4 push -0x1c(%ebp) + 6d3: e8 4b fc ff ff call 323 + if (p == (char*)-1) { + 6d8: 83 c4 10 add $0x10,%esp + 6db: 83 f8 ff cmp $0xffffffff,%eax + 6de: 74 1c je 6fc + hp->s.size = nu; + 6e0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6e3: 83 ec 0c sub $0xc,%esp + 6e6: 83 c0 08 add $0x8,%eax + 6e9: 50 push %eax + 6ea: e8 f1 fe ff ff call 5e0 + return freep; + 6ef: 8b 15 ac 0a 00 00 mov 0xaac,%edx + if ((p = morecore(nunits)) == 0) { + 6f5: 83 c4 10 add $0x10,%esp + 6f8: 85 d2 test %edx,%edx + 6fa: 75 bc jne 6b8 + return 0; + } + } + } +} + 6fc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 6ff: 31 c0 xor %eax,%eax +} + 701: 5b pop %ebx + 702: 5e pop %esi + 703: 5f pop %edi + 704: 5d pop %ebp + 705: c3 ret + if (p->s.size >= nunits) { + 706: 89 d0 mov %edx,%eax + 708: 89 fa mov %edi,%edx + 70a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 710: 39 ce cmp %ecx,%esi + 712: 74 4c je 760 + p->s.size -= nunits; + 714: 29 f1 sub %esi,%ecx + 716: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 719: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 71c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 71f: 89 15 ac 0a 00 00 mov %edx,0xaac +} + 725: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 728: 83 c0 08 add $0x8,%eax +} + 72b: 5b pop %ebx + 72c: 5e pop %esi + 72d: 5f pop %edi + 72e: 5d pop %ebp + 72f: c3 ret + base.s.ptr = freep = prevp = &base; + 730: c7 05 ac 0a 00 00 b0 movl $0xab0,0xaac + 737: 0a 00 00 + base.s.size = 0; + 73a: bf b0 0a 00 00 mov $0xab0,%edi + base.s.ptr = freep = prevp = &base; + 73f: c7 05 b0 0a 00 00 b0 movl $0xab0,0xab0 + 746: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 749: 89 fa mov %edi,%edx + base.s.size = 0; + 74b: c7 05 b4 0a 00 00 00 movl $0x0,0xab4 + 752: 00 00 00 + if (p->s.size >= nunits) { + 755: e9 42 ff ff ff jmp 69c + 75a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 760: 8b 08 mov (%eax),%ecx + 762: 89 0a mov %ecx,(%edx) + 764: eb b9 jmp 71f diff --git a/rm.c b/rm.c new file mode 100644 index 0000000..022afba --- /dev/null +++ b/rm.c @@ -0,0 +1,21 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(int argc, char *argv[]) { + int i; + + if (argc < 2) { + printf(2, "Usage: rm files...\n"); + exit(); + } + + for (i = 1; i < argc; i++) { + if (unlink(argv[i]) < 0) { + printf(2, "rm: %s failed to delete\n", argv[i]); + break; + } + } + + exit(); +} diff --git a/rm.d b/rm.d new file mode 100644 index 0000000..ba50b6b --- /dev/null +++ b/rm.d @@ -0,0 +1 @@ +rm.o: rm.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/rm.o b/rm.o new file mode 100644 index 0000000..956828c Binary files /dev/null and b/rm.o differ diff --git a/rm.sym b/rm.sym new file mode 100644 index 0000000..ce6632b --- /dev/null +++ b/rm.sym @@ -0,0 +1,48 @@ +00000000 rm.c +00000000 ulib.c +00000000 printf.c +00000390 printint +000007f4 digits.0 +00000000 umalloc.c +00000aac freep +00000ab0 base +00000080 strcpy +00000440 printf +0000037b greeting +000002a0 memmove +0000034b mknod +000001a0 gets +0000031b getpid +00000670 malloc +0000032b sleep +000002e3 pipe +00000373 getch +00000343 write +00000303 fstat +000002f3 kill +0000030b chdir +000002fb exec +000002db wait +000002eb read +00000353 unlink +000002cb fork +00000323 sbrk +00000333 uptime +00000aac __bss_start +00000140 memset +00000000 main +000000b0 strcmp +00000383 shutdown +00000313 dup +00000210 stat +00000aac _edata +00000ab8 _end +0000035b link +000002d3 exit +00000260 atoi +00000110 strlen +0000033b open +00000160 strchr +00000363 mkdir +0000036b close +000005e0 free diff --git a/screen.asm b/screen.asm new file mode 100644 index 0000000..931269b --- /dev/null +++ b/screen.asm @@ -0,0 +1,1202 @@ + +_screen: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: 53 push %ebx + 10: 51 push %ecx + 11: 83 ec 08 sub $0x8,%esp + 14: 8b 31 mov (%ecx),%esi + 16: 8b 79 04 mov 0x4(%ecx),%edi + //int consoles = 0; + int pid; + //char* comment = ""; + + for (int i = 1; i < argc; i++) { + 19: 83 fe 01 cmp $0x1,%esi + 1c: 7e 24 jle 42 + 1e: bb 01 00 00 00 mov $0x1,%ebx + 23: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 27: 90 nop + if (strcmp(argv[i], "-c") == 0) { + 28: 83 ec 08 sub $0x8,%esp + 2b: 68 78 07 00 00 push $0x778 + 30: ff 34 9f push (%edi,%ebx,4) + for (int i = 1; i < argc; i++) { + 33: 83 c3 01 add $0x1,%ebx + if (strcmp(argv[i], "-c") == 0) { + 36: e8 85 00 00 00 call c0 + for (int i = 1; i < argc; i++) { + 3b: 83 c4 10 add $0x10,%esp + 3e: 39 de cmp %ebx,%esi + 40: 75 e6 jne 28 + + } + } + + pid = fork(); + 42: e8 94 02 00 00 call 2db + if (pid < 0) { + 47: 85 c0 test %eax,%eax + 49: 78 27 js 72 + printf(1, "screen: fork failed\n"); + } + if (pid == 0) { + 4b: 74 05 je 52 + exec("sh", argv); + printf(1, "screen: exec sh failed\n"); + } + exit(); + 4d: e8 91 02 00 00 call 2e3 + exec("sh", argv); + 52: 50 push %eax + 53: 50 push %eax + 54: 57 push %edi + 55: 68 90 07 00 00 push $0x790 + 5a: e8 ac 02 00 00 call 30b + printf(1, "screen: exec sh failed\n"); + 5f: 5a pop %edx + 60: 59 pop %ecx + 61: 68 93 07 00 00 push $0x793 + 66: 6a 01 push $0x1 + 68: e8 e3 03 00 00 call 450 + 6d: 83 c4 10 add $0x10,%esp + 70: eb db jmp 4d + printf(1, "screen: fork failed\n"); + 72: 53 push %ebx + 73: 53 push %ebx + 74: 68 7b 07 00 00 push $0x77b + 79: 6a 01 push $0x1 + 7b: e8 d0 03 00 00 call 450 + 80: 83 c4 10 add $0x10,%esp + 83: eb c8 jmp 4d + 85: 66 90 xchg %ax,%ax + 87: 66 90 xchg %ax,%ax + 89: 66 90 xchg %ax,%ax + 8b: 66 90 xchg %ax,%ax + 8d: 66 90 xchg %ax,%ax + 8f: 90 nop + +00000090 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 90: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 91: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 93: 89 e5 mov %esp,%ebp + 95: 53 push %ebx + 96: 8b 4d 08 mov 0x8(%ebp),%ecx + 99: 8b 5d 0c mov 0xc(%ebp),%ebx + 9c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + a0: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + a4: 88 14 01 mov %dl,(%ecx,%eax,1) + a7: 83 c0 01 add $0x1,%eax + aa: 84 d2 test %dl,%dl + ac: 75 f2 jne a0 + ; + } + return os; +} + ae: 8b 5d fc mov -0x4(%ebp),%ebx + b1: 89 c8 mov %ecx,%eax + b3: c9 leave + b4: c3 ret + b5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + bc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000000c0 : + +int strcmp(const char *p, const char *q) { + c0: 55 push %ebp + c1: 89 e5 mov %esp,%ebp + c3: 53 push %ebx + c4: 8b 55 08 mov 0x8(%ebp),%edx + c7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + ca: 0f b6 02 movzbl (%edx),%eax + cd: 84 c0 test %al,%al + cf: 75 17 jne e8 + d1: eb 3a jmp 10d + d3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + d7: 90 nop + d8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + dc: 83 c2 01 add $0x1,%edx + df: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + e2: 84 c0 test %al,%al + e4: 74 1a je 100 + p++, q++; + e6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + e8: 0f b6 19 movzbl (%ecx),%ebx + eb: 38 c3 cmp %al,%bl + ed: 74 e9 je d8 + } + return (uchar) * p - (uchar) * q; + ef: 29 d8 sub %ebx,%eax +} + f1: 8b 5d fc mov -0x4(%ebp),%ebx + f4: c9 leave + f5: c3 ret + f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + fd: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 100: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 104: 31 c0 xor %eax,%eax + 106: 29 d8 sub %ebx,%eax +} + 108: 8b 5d fc mov -0x4(%ebp),%ebx + 10b: c9 leave + 10c: c3 ret + return (uchar) * p - (uchar) * q; + 10d: 0f b6 19 movzbl (%ecx),%ebx + 110: 31 c0 xor %eax,%eax + 112: eb db jmp ef + 114: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 11b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 11f: 90 nop + +00000120 : + +uint strlen(const char *s) { + 120: 55 push %ebp + 121: 89 e5 mov %esp,%ebp + 123: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 126: 80 3a 00 cmpb $0x0,(%edx) + 129: 74 15 je 140 + 12b: 31 c0 xor %eax,%eax + 12d: 8d 76 00 lea 0x0(%esi),%esi + 130: 83 c0 01 add $0x1,%eax + 133: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 137: 89 c1 mov %eax,%ecx + 139: 75 f5 jne 130 + ; + } + return n; +} + 13b: 89 c8 mov %ecx,%eax + 13d: 5d pop %ebp + 13e: c3 ret + 13f: 90 nop + for (n = 0; s[n]; n++) { + 140: 31 c9 xor %ecx,%ecx +} + 142: 5d pop %ebp + 143: 89 c8 mov %ecx,%eax + 145: c3 ret + 146: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 14d: 8d 76 00 lea 0x0(%esi),%esi + +00000150 : + +void* memset(void *dst, int c, uint n) { + 150: 55 push %ebp + 151: 89 e5 mov %esp,%ebp + 153: 57 push %edi + 154: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 157: 8b 4d 10 mov 0x10(%ebp),%ecx + 15a: 8b 45 0c mov 0xc(%ebp),%eax + 15d: 89 d7 mov %edx,%edi + 15f: fc cld + 160: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 162: 8b 7d fc mov -0x4(%ebp),%edi + 165: 89 d0 mov %edx,%eax + 167: c9 leave + 168: c3 ret + 169: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000170 : + +char* strchr(const char *s, char c) { + 170: 55 push %ebp + 171: 89 e5 mov %esp,%ebp + 173: 8b 45 08 mov 0x8(%ebp),%eax + 176: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 17a: 0f b6 10 movzbl (%eax),%edx + 17d: 84 d2 test %dl,%dl + 17f: 75 12 jne 193 + 181: eb 1d jmp 1a0 + 183: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 187: 90 nop + 188: 0f b6 50 01 movzbl 0x1(%eax),%edx + 18c: 83 c0 01 add $0x1,%eax + 18f: 84 d2 test %dl,%dl + 191: 74 0d je 1a0 + if (*s == c) { + 193: 38 d1 cmp %dl,%cl + 195: 75 f1 jne 188 + return (char*)s; + } + } + return 0; +} + 197: 5d pop %ebp + 198: c3 ret + 199: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 1a0: 31 c0 xor %eax,%eax +} + 1a2: 5d pop %ebp + 1a3: c3 ret + 1a4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1af: 90 nop + +000001b0 : + +char* gets(char *buf, int max) { + 1b0: 55 push %ebp + 1b1: 89 e5 mov %esp,%ebp + 1b3: 57 push %edi + 1b4: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 1b5: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 1b8: 53 push %ebx + for (i = 0; i + 1 < max;) { + 1b9: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 1bb: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 1be: eb 27 jmp 1e7 + cc = read(0, &c, 1); + 1c0: 83 ec 04 sub $0x4,%esp + 1c3: 6a 01 push $0x1 + 1c5: 57 push %edi + 1c6: 6a 00 push $0x0 + 1c8: e8 2e 01 00 00 call 2fb + if (cc < 1) { + 1cd: 83 c4 10 add $0x10,%esp + 1d0: 85 c0 test %eax,%eax + 1d2: 7e 1d jle 1f1 + break; + } + buf[i++] = c; + 1d4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 1d8: 8b 55 08 mov 0x8(%ebp),%edx + 1db: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 1df: 3c 0a cmp $0xa,%al + 1e1: 74 1d je 200 + 1e3: 3c 0d cmp $0xd,%al + 1e5: 74 19 je 200 + for (i = 0; i + 1 < max;) { + 1e7: 89 de mov %ebx,%esi + 1e9: 83 c3 01 add $0x1,%ebx + 1ec: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1ef: 7c cf jl 1c0 + break; + } + } + buf[i] = '\0'; + 1f1: 8b 45 08 mov 0x8(%ebp),%eax + 1f4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1f8: 8d 65 f4 lea -0xc(%ebp),%esp + 1fb: 5b pop %ebx + 1fc: 5e pop %esi + 1fd: 5f pop %edi + 1fe: 5d pop %ebp + 1ff: c3 ret + buf[i] = '\0'; + 200: 8b 45 08 mov 0x8(%ebp),%eax + 203: 89 de mov %ebx,%esi + 205: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 209: 8d 65 f4 lea -0xc(%ebp),%esp + 20c: 5b pop %ebx + 20d: 5e pop %esi + 20e: 5f pop %edi + 20f: 5d pop %ebp + 210: c3 ret + 211: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 218: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 21f: 90 nop + +00000220 : + +int stat(const char *n, struct stat *st) { + 220: 55 push %ebp + 221: 89 e5 mov %esp,%ebp + 223: 56 push %esi + 224: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 225: 83 ec 08 sub $0x8,%esp + 228: 6a 00 push $0x0 + 22a: ff 75 08 push 0x8(%ebp) + 22d: e8 19 01 00 00 call 34b + if (fd < 0) { + 232: 83 c4 10 add $0x10,%esp + 235: 85 c0 test %eax,%eax + 237: 78 27 js 260 + return -1; + } + r = fstat(fd, st); + 239: 83 ec 08 sub $0x8,%esp + 23c: ff 75 0c push 0xc(%ebp) + 23f: 89 c3 mov %eax,%ebx + 241: 50 push %eax + 242: e8 cc 00 00 00 call 313 + close(fd); + 247: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 24a: 89 c6 mov %eax,%esi + close(fd); + 24c: e8 2a 01 00 00 call 37b + return r; + 251: 83 c4 10 add $0x10,%esp +} + 254: 8d 65 f8 lea -0x8(%ebp),%esp + 257: 89 f0 mov %esi,%eax + 259: 5b pop %ebx + 25a: 5e pop %esi + 25b: 5d pop %ebp + 25c: c3 ret + 25d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 260: be ff ff ff ff mov $0xffffffff,%esi + 265: eb ed jmp 254 + 267: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 26e: 66 90 xchg %ax,%ax + +00000270 : + +int atoi(const char *s) { + 270: 55 push %ebp + 271: 89 e5 mov %esp,%ebp + 273: 53 push %ebx + 274: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 277: 0f be 02 movsbl (%edx),%eax + 27a: 8d 48 d0 lea -0x30(%eax),%ecx + 27d: 80 f9 09 cmp $0x9,%cl + n = 0; + 280: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 285: 77 1e ja 2a5 + 287: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 28e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 290: 83 c2 01 add $0x1,%edx + 293: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 296: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 29a: 0f be 02 movsbl (%edx),%eax + 29d: 8d 58 d0 lea -0x30(%eax),%ebx + 2a0: 80 fb 09 cmp $0x9,%bl + 2a3: 76 eb jbe 290 + } + return n; +} + 2a5: 8b 5d fc mov -0x4(%ebp),%ebx + 2a8: 89 c8 mov %ecx,%eax + 2aa: c9 leave + 2ab: c3 ret + 2ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000002b0 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 2b0: 55 push %ebp + 2b1: 89 e5 mov %esp,%ebp + 2b3: 57 push %edi + 2b4: 8b 45 10 mov 0x10(%ebp),%eax + 2b7: 8b 55 08 mov 0x8(%ebp),%edx + 2ba: 56 push %esi + 2bb: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 2be: 85 c0 test %eax,%eax + 2c0: 7e 13 jle 2d5 + 2c2: 01 d0 add %edx,%eax + dst = vdst; + 2c4: 89 d7 mov %edx,%edi + 2c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2cd: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 2d0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 2d1: 39 f8 cmp %edi,%eax + 2d3: 75 fb jne 2d0 + } + return vdst; +} + 2d5: 5e pop %esi + 2d6: 89 d0 mov %edx,%eax + 2d8: 5f pop %edi + 2d9: 5d pop %ebp + 2da: c3 ret + +000002db : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 2db: b8 01 00 00 00 mov $0x1,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(exit) + 2e3: b8 02 00 00 00 mov $0x2,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(wait) + 2eb: b8 03 00 00 00 mov $0x3,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(pipe) + 2f3: b8 04 00 00 00 mov $0x4,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(read) + 2fb: b8 05 00 00 00 mov $0x5,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(kill) + 303: b8 06 00 00 00 mov $0x6,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(exec) + 30b: b8 07 00 00 00 mov $0x7,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(fstat) + 313: b8 08 00 00 00 mov $0x8,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(chdir) + 31b: b8 09 00 00 00 mov $0x9,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(dup) + 323: b8 0a 00 00 00 mov $0xa,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(getpid) + 32b: b8 0b 00 00 00 mov $0xb,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(sbrk) + 333: b8 0c 00 00 00 mov $0xc,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(sleep) + 33b: b8 0d 00 00 00 mov $0xd,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(uptime) + 343: b8 0e 00 00 00 mov $0xe,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(open) + 34b: b8 0f 00 00 00 mov $0xf,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(write) + 353: b8 10 00 00 00 mov $0x10,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(mknod) + 35b: b8 11 00 00 00 mov $0x11,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(unlink) + 363: b8 12 00 00 00 mov $0x12,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + +0000036b : +SYSCALL(link) + 36b: b8 13 00 00 00 mov $0x13,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(mkdir) + 373: b8 14 00 00 00 mov $0x14,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + +0000037b : +SYSCALL(close) + 37b: b8 15 00 00 00 mov $0x15,%eax + 380: cd 40 int $0x40 + 382: c3 ret + +00000383 : +SYSCALL(getch) + 383: b8 16 00 00 00 mov $0x16,%eax + 388: cd 40 int $0x40 + 38a: c3 ret + +0000038b : +SYSCALL(greeting) + 38b: b8 17 00 00 00 mov $0x17,%eax + 390: cd 40 int $0x40 + 392: c3 ret + +00000393 : +SYSCALL(shutdown) + 393: b8 18 00 00 00 mov $0x18,%eax + 398: cd 40 int $0x40 + 39a: c3 ret + 39b: 66 90 xchg %ax,%ax + 39d: 66 90 xchg %ax,%ax + 39f: 90 nop + +000003a0 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 3a0: 55 push %ebp + 3a1: 89 e5 mov %esp,%ebp + 3a3: 57 push %edi + 3a4: 56 push %esi + 3a5: 53 push %ebx + 3a6: 83 ec 3c sub $0x3c,%esp + 3a9: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 3ac: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 3ae: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 3b1: 85 d2 test %edx,%edx + 3b3: 0f 89 7f 00 00 00 jns 438 + 3b9: f6 45 08 01 testb $0x1,0x8(%ebp) + 3bd: 74 79 je 438 + neg = 1; + 3bf: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 3c6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 3c8: 31 db xor %ebx,%ebx + 3ca: 8d 75 d7 lea -0x29(%ebp),%esi + 3cd: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 3d0: 89 c8 mov %ecx,%eax + 3d2: 31 d2 xor %edx,%edx + 3d4: 89 cf mov %ecx,%edi + 3d6: f7 75 c4 divl -0x3c(%ebp) + 3d9: 0f b6 92 0c 08 00 00 movzbl 0x80c(%edx),%edx + 3e0: 89 45 c0 mov %eax,-0x40(%ebp) + 3e3: 89 d8 mov %ebx,%eax + 3e5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3e8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3eb: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3ee: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3f1: 76 dd jbe 3d0 + if (neg) { + 3f3: 8b 4d bc mov -0x44(%ebp),%ecx + 3f6: 85 c9 test %ecx,%ecx + 3f8: 74 0c je 406 + buf[i++] = '-'; + 3fa: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3ff: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 401: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 406: 8b 7d b8 mov -0x48(%ebp),%edi + 409: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 40d: eb 07 jmp 416 + 40f: 90 nop + putc(fd, buf[i]); + 410: 0f b6 13 movzbl (%ebx),%edx + 413: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 416: 83 ec 04 sub $0x4,%esp + 419: 88 55 d7 mov %dl,-0x29(%ebp) + 41c: 6a 01 push $0x1 + 41e: 56 push %esi + 41f: 57 push %edi + 420: e8 2e ff ff ff call 353 + while (--i >= 0) { + 425: 83 c4 10 add $0x10,%esp + 428: 39 de cmp %ebx,%esi + 42a: 75 e4 jne 410 + } +} + 42c: 8d 65 f4 lea -0xc(%ebp),%esp + 42f: 5b pop %ebx + 430: 5e pop %esi + 431: 5f pop %edi + 432: 5d pop %ebp + 433: c3 ret + 434: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 438: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 43f: eb 87 jmp 3c8 + 441: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 448: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 44f: 90 nop + +00000450 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 450: 55 push %ebp + 451: 89 e5 mov %esp,%ebp + 453: 57 push %edi + 454: 56 push %esi + 455: 53 push %ebx + 456: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 459: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 45c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 45f: 0f b6 13 movzbl (%ebx),%edx + 462: 84 d2 test %dl,%dl + 464: 74 6a je 4d0 + ap = (uint*)(void*)&fmt + 1; + 466: 8d 45 10 lea 0x10(%ebp),%eax + 469: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 46c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 46f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 471: 89 45 d0 mov %eax,-0x30(%ebp) + 474: eb 36 jmp 4ac + 476: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 47d: 8d 76 00 lea 0x0(%esi),%esi + 480: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 483: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 488: 83 f8 25 cmp $0x25,%eax + 48b: 74 15 je 4a2 + write(fd, &c, 1); + 48d: 83 ec 04 sub $0x4,%esp + 490: 88 55 e7 mov %dl,-0x19(%ebp) + 493: 6a 01 push $0x1 + 495: 57 push %edi + 496: 56 push %esi + 497: e8 b7 fe ff ff call 353 + 49c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 49f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 4a2: 0f b6 13 movzbl (%ebx),%edx + 4a5: 83 c3 01 add $0x1,%ebx + 4a8: 84 d2 test %dl,%dl + 4aa: 74 24 je 4d0 + c = fmt[i] & 0xff; + 4ac: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 4af: 85 c9 test %ecx,%ecx + 4b1: 74 cd je 480 + } + } + else if (state == '%') { + 4b3: 83 f9 25 cmp $0x25,%ecx + 4b6: 75 ea jne 4a2 + if (c == 'd') { + 4b8: 83 f8 25 cmp $0x25,%eax + 4bb: 0f 84 07 01 00 00 je 5c8 + 4c1: 83 e8 63 sub $0x63,%eax + 4c4: 83 f8 15 cmp $0x15,%eax + 4c7: 77 17 ja 4e0 + 4c9: ff 24 85 b4 07 00 00 jmp *0x7b4(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 4d0: 8d 65 f4 lea -0xc(%ebp),%esp + 4d3: 5b pop %ebx + 4d4: 5e pop %esi + 4d5: 5f pop %edi + 4d6: 5d pop %ebp + 4d7: c3 ret + 4d8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4df: 90 nop + write(fd, &c, 1); + 4e0: 83 ec 04 sub $0x4,%esp + 4e3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4e6: 6a 01 push $0x1 + 4e8: 57 push %edi + 4e9: 56 push %esi + 4ea: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4ee: e8 60 fe ff ff call 353 + putc(fd, c); + 4f3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4f7: 83 c4 0c add $0xc,%esp + 4fa: 88 55 e7 mov %dl,-0x19(%ebp) + 4fd: 6a 01 push $0x1 + 4ff: 57 push %edi + 500: 56 push %esi + 501: e8 4d fe ff ff call 353 + putc(fd, c); + 506: 83 c4 10 add $0x10,%esp + state = 0; + 509: 31 c9 xor %ecx,%ecx + 50b: eb 95 jmp 4a2 + 50d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 510: 83 ec 0c sub $0xc,%esp + 513: b9 10 00 00 00 mov $0x10,%ecx + 518: 6a 00 push $0x0 + 51a: 8b 45 d0 mov -0x30(%ebp),%eax + 51d: 8b 10 mov (%eax),%edx + 51f: 89 f0 mov %esi,%eax + 521: e8 7a fe ff ff call 3a0 + ap++; + 526: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 52a: 83 c4 10 add $0x10,%esp + state = 0; + 52d: 31 c9 xor %ecx,%ecx + 52f: e9 6e ff ff ff jmp 4a2 + 534: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 538: 8b 45 d0 mov -0x30(%ebp),%eax + 53b: 8b 10 mov (%eax),%edx + ap++; + 53d: 83 c0 04 add $0x4,%eax + 540: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 543: 85 d2 test %edx,%edx + 545: 0f 84 8d 00 00 00 je 5d8 + while (*s != 0) { + 54b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 54e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 550: 84 c0 test %al,%al + 552: 0f 84 4a ff ff ff je 4a2 + 558: 89 5d d4 mov %ebx,-0x2c(%ebp) + 55b: 89 d3 mov %edx,%ebx + 55d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 560: 83 ec 04 sub $0x4,%esp + s++; + 563: 83 c3 01 add $0x1,%ebx + 566: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 569: 6a 01 push $0x1 + 56b: 57 push %edi + 56c: 56 push %esi + 56d: e8 e1 fd ff ff call 353 + while (*s != 0) { + 572: 0f b6 03 movzbl (%ebx),%eax + 575: 83 c4 10 add $0x10,%esp + 578: 84 c0 test %al,%al + 57a: 75 e4 jne 560 + state = 0; + 57c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 57f: 31 c9 xor %ecx,%ecx + 581: e9 1c ff ff ff jmp 4a2 + 586: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 58d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 590: 83 ec 0c sub $0xc,%esp + 593: b9 0a 00 00 00 mov $0xa,%ecx + 598: 6a 01 push $0x1 + 59a: e9 7b ff ff ff jmp 51a + 59f: 90 nop + putc(fd, *ap); + 5a0: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 5a3: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 5a6: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 5a8: 6a 01 push $0x1 + 5aa: 57 push %edi + 5ab: 56 push %esi + putc(fd, *ap); + 5ac: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 5af: e8 9f fd ff ff call 353 + ap++; + 5b4: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 5b8: 83 c4 10 add $0x10,%esp + state = 0; + 5bb: 31 c9 xor %ecx,%ecx + 5bd: e9 e0 fe ff ff jmp 4a2 + 5c2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 5c8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 5cb: 83 ec 04 sub $0x4,%esp + 5ce: e9 2a ff ff ff jmp 4fd + 5d3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 5d7: 90 nop + s = "(null)"; + 5d8: ba ab 07 00 00 mov $0x7ab,%edx + while (*s != 0) { + 5dd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5e0: b8 28 00 00 00 mov $0x28,%eax + 5e5: 89 d3 mov %edx,%ebx + 5e7: e9 74 ff ff ff jmp 560 + 5ec: 66 90 xchg %ax,%ax + 5ee: 66 90 xchg %ax,%ax + +000005f0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5f0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5f1: a1 c0 0a 00 00 mov 0xac0,%eax +void free(void *ap) { + 5f6: 89 e5 mov %esp,%ebp + 5f8: 57 push %edi + 5f9: 56 push %esi + 5fa: 53 push %ebx + 5fb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5fe: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 601: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 608: 89 c2 mov %eax,%edx + 60a: 8b 00 mov (%eax),%eax + 60c: 39 ca cmp %ecx,%edx + 60e: 73 30 jae 640 + 610: 39 c1 cmp %eax,%ecx + 612: 72 04 jb 618 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 614: 39 c2 cmp %eax,%edx + 616: 72 f0 jb 608 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 618: 8b 73 fc mov -0x4(%ebx),%esi + 61b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 61e: 39 f8 cmp %edi,%eax + 620: 74 30 je 652 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 622: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 625: 8b 42 04 mov 0x4(%edx),%eax + 628: 8d 34 c2 lea (%edx,%eax,8),%esi + 62b: 39 f1 cmp %esi,%ecx + 62d: 74 3a je 669 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 62f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 631: 5b pop %ebx + freep = p; + 632: 89 15 c0 0a 00 00 mov %edx,0xac0 +} + 638: 5e pop %esi + 639: 5f pop %edi + 63a: 5d pop %ebp + 63b: c3 ret + 63c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 640: 39 c2 cmp %eax,%edx + 642: 72 c4 jb 608 + 644: 39 c1 cmp %eax,%ecx + 646: 73 c0 jae 608 + if (bp + bp->s.size == p->s.ptr) { + 648: 8b 73 fc mov -0x4(%ebx),%esi + 64b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 64e: 39 f8 cmp %edi,%eax + 650: 75 d0 jne 622 + bp->s.size += p->s.ptr->s.size; + 652: 03 70 04 add 0x4(%eax),%esi + 655: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 658: 8b 02 mov (%edx),%eax + 65a: 8b 00 mov (%eax),%eax + 65c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 65f: 8b 42 04 mov 0x4(%edx),%eax + 662: 8d 34 c2 lea (%edx,%eax,8),%esi + 665: 39 f1 cmp %esi,%ecx + 667: 75 c6 jne 62f + p->s.size += bp->s.size; + 669: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 66c: 89 15 c0 0a 00 00 mov %edx,0xac0 + p->s.size += bp->s.size; + 672: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 675: 8b 4b f8 mov -0x8(%ebx),%ecx + 678: 89 0a mov %ecx,(%edx) +} + 67a: 5b pop %ebx + 67b: 5e pop %esi + 67c: 5f pop %edi + 67d: 5d pop %ebp + 67e: c3 ret + 67f: 90 nop + +00000680 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 680: 55 push %ebp + 681: 89 e5 mov %esp,%ebp + 683: 57 push %edi + 684: 56 push %esi + 685: 53 push %ebx + 686: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 689: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 68c: 8b 3d c0 0a 00 00 mov 0xac0,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 692: 8d 70 07 lea 0x7(%eax),%esi + 695: c1 ee 03 shr $0x3,%esi + 698: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 69b: 85 ff test %edi,%edi + 69d: 0f 84 9d 00 00 00 je 740 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6a3: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 6a5: 8b 4a 04 mov 0x4(%edx),%ecx + 6a8: 39 f1 cmp %esi,%ecx + 6aa: 73 6a jae 716 + 6ac: bb 00 10 00 00 mov $0x1000,%ebx + 6b1: 39 de cmp %ebx,%esi + 6b3: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 6b6: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 6bd: 89 45 e4 mov %eax,-0x1c(%ebp) + 6c0: eb 17 jmp 6d9 + 6c2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6c8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 6ca: 8b 48 04 mov 0x4(%eax),%ecx + 6cd: 39 f1 cmp %esi,%ecx + 6cf: 73 4f jae 720 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 6d1: 8b 3d c0 0a 00 00 mov 0xac0,%edi + 6d7: 89 c2 mov %eax,%edx + 6d9: 39 d7 cmp %edx,%edi + 6db: 75 eb jne 6c8 + p = sbrk(nu * sizeof(Header)); + 6dd: 83 ec 0c sub $0xc,%esp + 6e0: ff 75 e4 push -0x1c(%ebp) + 6e3: e8 4b fc ff ff call 333 + if (p == (char*)-1) { + 6e8: 83 c4 10 add $0x10,%esp + 6eb: 83 f8 ff cmp $0xffffffff,%eax + 6ee: 74 1c je 70c + hp->s.size = nu; + 6f0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6f3: 83 ec 0c sub $0xc,%esp + 6f6: 83 c0 08 add $0x8,%eax + 6f9: 50 push %eax + 6fa: e8 f1 fe ff ff call 5f0 + return freep; + 6ff: 8b 15 c0 0a 00 00 mov 0xac0,%edx + if ((p = morecore(nunits)) == 0) { + 705: 83 c4 10 add $0x10,%esp + 708: 85 d2 test %edx,%edx + 70a: 75 bc jne 6c8 + return 0; + } + } + } +} + 70c: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 70f: 31 c0 xor %eax,%eax +} + 711: 5b pop %ebx + 712: 5e pop %esi + 713: 5f pop %edi + 714: 5d pop %ebp + 715: c3 ret + if (p->s.size >= nunits) { + 716: 89 d0 mov %edx,%eax + 718: 89 fa mov %edi,%edx + 71a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 720: 39 ce cmp %ecx,%esi + 722: 74 4c je 770 + p->s.size -= nunits; + 724: 29 f1 sub %esi,%ecx + 726: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 729: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 72c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 72f: 89 15 c0 0a 00 00 mov %edx,0xac0 +} + 735: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 738: 83 c0 08 add $0x8,%eax +} + 73b: 5b pop %ebx + 73c: 5e pop %esi + 73d: 5f pop %edi + 73e: 5d pop %ebp + 73f: c3 ret + base.s.ptr = freep = prevp = &base; + 740: c7 05 c0 0a 00 00 c4 movl $0xac4,0xac0 + 747: 0a 00 00 + base.s.size = 0; + 74a: bf c4 0a 00 00 mov $0xac4,%edi + base.s.ptr = freep = prevp = &base; + 74f: c7 05 c4 0a 00 00 c4 movl $0xac4,0xac4 + 756: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 759: 89 fa mov %edi,%edx + base.s.size = 0; + 75b: c7 05 c8 0a 00 00 00 movl $0x0,0xac8 + 762: 00 00 00 + if (p->s.size >= nunits) { + 765: e9 42 ff ff ff jmp 6ac + 76a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 770: 8b 08 mov (%eax),%ecx + 772: 89 0a mov %ecx,(%edx) + 774: eb b9 jmp 72f diff --git a/screen.c b/screen.c new file mode 100644 index 0000000..e8feaa8 --- /dev/null +++ b/screen.c @@ -0,0 +1,24 @@ +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + //int consoles = 0; + int pid; + //char* comment = ""; + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0) { + + } + } + + pid = fork(); + if (pid < 0) { + printf(1, "screen: fork failed\n"); + } + if (pid == 0) { + exec("sh", argv); + printf(1, "screen: exec sh failed\n"); + } + exit(); +} \ No newline at end of file diff --git a/screen.d b/screen.d new file mode 100644 index 0000000..38dc977 --- /dev/null +++ b/screen.d @@ -0,0 +1 @@ +screen.o: screen.c /usr/include/stdc-predef.h types.h user.h diff --git a/screen.o b/screen.o new file mode 100644 index 0000000..f5d851c Binary files /dev/null and b/screen.o differ diff --git a/screen.sym b/screen.sym new file mode 100644 index 0000000..478d8de --- /dev/null +++ b/screen.sym @@ -0,0 +1,48 @@ +00000000 screen.c +00000000 ulib.c +00000000 printf.c +000003a0 printint +0000080c digits.0 +00000000 umalloc.c +00000ac0 freep +00000ac4 base +00000090 strcpy +00000450 printf +0000038b greeting +000002b0 memmove +0000035b mknod +000001b0 gets +0000032b getpid +00000680 malloc +0000033b sleep +000002f3 pipe +00000383 getch +00000353 write +00000313 fstat +00000303 kill +0000031b chdir +0000030b exec +000002eb wait +000002fb read +00000363 unlink +000002db fork +00000333 sbrk +00000343 uptime +00000ac0 __bss_start +00000150 memset +00000000 main +000000c0 strcmp +00000393 shutdown +00000323 dup +00000220 stat +00000ac0 _edata +00000acc _end +0000036b link +000002e3 exit +00000270 atoi +00000120 strlen +0000034b open +00000170 strchr +00000373 mkdir +0000037b close +000005f0 free diff --git a/sh.asm b/sh.asm new file mode 100644 index 0000000..5e0eb6a --- /dev/null +++ b/sh.asm @@ -0,0 +1,2715 @@ + +_sh: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: + return -1; + } + return 0; +} + +int main(void) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 51 push %ecx + e: 83 ec 04 sub $0x4,%esp + static char buf[100]; + int fd; + + // Ensure that three file descriptors are open. + while ((fd = open("console", O_RDWR)) >= 0) { + 11: eb 0e jmp 21 + 13: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 17: 90 nop + if (fd >= 3) { + 18: 83 f8 02 cmp $0x2,%eax + 1b: 0f 8f 01 01 00 00 jg 122 + while ((fd = open("console", O_RDWR)) >= 0) { + 21: 83 ec 08 sub $0x8,%esp + 24: 6a 02 push $0x2 + 26: 68 89 13 00 00 push $0x1389 + 2b: e8 8b 0e 00 00 call ebb + 30: 83 c4 10 add $0x10,%esp + 33: 85 c0 test %eax,%eax + 35: 79 e1 jns 18 + 37: eb 33 jmp 6c + 39: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + // Read and run input commands. + while (getcmd(buf, sizeof(buf)) >= 0) { + if (buf[0] == 'e' && buf[1] == 'x' && buf[2] == 'i' && buf[3] == 't') { + exit(); + } + if (buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' ') { + 40: 3c 63 cmp $0x63,%al + 42: 75 0d jne 51 + 44: 80 3d 21 1a 00 00 64 cmpb $0x64,0x1a21 + 4b: 0f 84 7f 00 00 00 je d0 +} + +int fork1(void) { + int pid; + + pid = fork(); + 51: e8 f5 0d 00 00 call e4b + if (pid == -1) { + 56: 83 f8 ff cmp $0xffffffff,%eax + 59: 0f 84 e9 00 00 00 je 148 + if (fork1() == 0) { + 5f: 85 c0 test %eax,%eax + 61: 0f 84 cc 00 00 00 je 133 + wait(); + 67: e8 ef 0d 00 00 call e5b + printf(2, "$ "); + 6c: 83 ec 08 sub $0x8,%esp + 6f: 68 e8 12 00 00 push $0x12e8 + 74: 6a 02 push $0x2 + 76: e8 45 0f 00 00 call fc0 + memset(buf, 0, nbuf); + 7b: 83 c4 0c add $0xc,%esp + 7e: 6a 64 push $0x64 + 80: 6a 00 push $0x0 + 82: 68 20 1a 00 00 push $0x1a20 + 87: e8 34 0c 00 00 call cc0 + gets(buf, nbuf); + 8c: 58 pop %eax + 8d: 5a pop %edx + 8e: 6a 64 push $0x64 + 90: 68 20 1a 00 00 push $0x1a20 + 95: e8 86 0c 00 00 call d20 + if (buf[0] == 0) { // EOF + 9a: 0f b6 05 20 1a 00 00 movzbl 0x1a20,%eax + a1: 83 c4 10 add $0x10,%esp + a4: 84 c0 test %al,%al + a6: 74 1f je c7 + if (buf[0] == 'e' && buf[1] == 'x' && buf[2] == 'i' && buf[3] == 't') { + a8: 3c 65 cmp $0x65,%al + aa: 75 94 jne 40 + ac: 80 3d 21 1a 00 00 78 cmpb $0x78,0x1a21 + b3: 75 9c jne 51 + b5: 80 3d 22 1a 00 00 69 cmpb $0x69,0x1a22 + bc: 75 93 jne 51 + be: 80 3d 23 1a 00 00 74 cmpb $0x74,0x1a23 + c5: 75 8a jne 51 + exit(); + c7: e8 87 0d 00 00 call e53 + cc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' ') { + d0: 80 3d 22 1a 00 00 20 cmpb $0x20,0x1a22 + d7: 0f 85 74 ff ff ff jne 51 + buf[strlen(buf) - 1] = 0; // chop \n + dd: 83 ec 0c sub $0xc,%esp + e0: 68 20 1a 00 00 push $0x1a20 + e5: e8 a6 0b 00 00 call c90 + if (chdir(buf + 3) < 0) { + ea: c7 04 24 23 1a 00 00 movl $0x1a23,(%esp) + buf[strlen(buf) - 1] = 0; // chop \n + f1: c6 80 1f 1a 00 00 00 movb $0x0,0x1a1f(%eax) + if (chdir(buf + 3) < 0) { + f8: e8 8e 0d 00 00 call e8b + fd: 83 c4 10 add $0x10,%esp + 100: 85 c0 test %eax,%eax + 102: 0f 89 64 ff ff ff jns 6c + printf(2, "cannot cd %s\n", buf + 3); + 108: 51 push %ecx + 109: 68 23 1a 00 00 push $0x1a23 + 10e: 68 91 13 00 00 push $0x1391 + 113: 6a 02 push $0x2 + 115: e8 a6 0e 00 00 call fc0 + 11a: 83 c4 10 add $0x10,%esp + 11d: e9 4a ff ff ff jmp 6c + close(fd); + 122: 83 ec 0c sub $0xc,%esp + 125: 50 push %eax + 126: e8 c0 0d 00 00 call eeb + break; + 12b: 83 c4 10 add $0x10,%esp + 12e: e9 39 ff ff ff jmp 6c + runcmd(parsecmd(buf)); + 133: 83 ec 0c sub $0xc,%esp + 136: 68 20 1a 00 00 push $0x1a20 + 13b: e8 50 0a 00 00 call b90 + 140: 89 04 24 mov %eax,(%esp) + 143: e8 98 00 00 00 call 1e0 + panic("fork"); + 148: 83 ec 0c sub $0xc,%esp + 14b: 68 eb 12 00 00 push $0x12eb + 150: e8 4b 00 00 00 call 1a0 + 155: 66 90 xchg %ax,%ax + 157: 66 90 xchg %ax,%ax + 159: 66 90 xchg %ax,%ax + 15b: 66 90 xchg %ax,%ax + 15d: 66 90 xchg %ax,%ax + 15f: 90 nop + +00000160 : +int getcmd(char *buf, int nbuf) { + 160: 55 push %ebp + 161: 89 e5 mov %esp,%ebp + 163: 56 push %esi + 164: 53 push %ebx + 165: 8b 75 0c mov 0xc(%ebp),%esi + 168: 8b 5d 08 mov 0x8(%ebp),%ebx + printf(2, "$ "); + 16b: 83 ec 08 sub $0x8,%esp + 16e: 68 e8 12 00 00 push $0x12e8 + 173: 6a 02 push $0x2 + 175: e8 46 0e 00 00 call fc0 + memset(buf, 0, nbuf); + 17a: 83 c4 0c add $0xc,%esp + 17d: 56 push %esi + 17e: 6a 00 push $0x0 + 180: 53 push %ebx + 181: e8 3a 0b 00 00 call cc0 + gets(buf, nbuf); + 186: 58 pop %eax + 187: 5a pop %edx + 188: 56 push %esi + 189: 53 push %ebx + 18a: e8 91 0b 00 00 call d20 + if (buf[0] == 0) { // EOF + 18f: 83 c4 10 add $0x10,%esp + 192: 80 3b 01 cmpb $0x1,(%ebx) + 195: 19 c0 sbb %eax,%eax +} + 197: 8d 65 f8 lea -0x8(%ebp),%esp + 19a: 5b pop %ebx + 19b: 5e pop %esi + 19c: 5d pop %ebp + 19d: c3 ret + 19e: 66 90 xchg %ax,%ax + +000001a0 : +void panic(char *s) { + 1a0: 55 push %ebp + 1a1: 89 e5 mov %esp,%ebp + 1a3: 83 ec 0c sub $0xc,%esp + printf(2, "%s\n", s); + 1a6: ff 75 08 push 0x8(%ebp) + 1a9: 68 85 13 00 00 push $0x1385 + 1ae: 6a 02 push $0x2 + 1b0: e8 0b 0e 00 00 call fc0 + exit(); + 1b5: e8 99 0c 00 00 call e53 + 1ba: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +000001c0 : +int fork1(void) { + 1c0: 55 push %ebp + 1c1: 89 e5 mov %esp,%ebp + 1c3: 83 ec 08 sub $0x8,%esp + pid = fork(); + 1c6: e8 80 0c 00 00 call e4b + if (pid == -1) { + 1cb: 83 f8 ff cmp $0xffffffff,%eax + 1ce: 74 02 je 1d2 + } + return pid; +} + 1d0: c9 leave + 1d1: c3 ret + panic("fork"); + 1d2: 83 ec 0c sub $0xc,%esp + 1d5: 68 eb 12 00 00 push $0x12eb + 1da: e8 c1 ff ff ff call 1a0 + 1df: 90 nop + +000001e0 : +void runcmd(struct cmd *cmd) { + 1e0: 55 push %ebp + 1e1: 89 e5 mov %esp,%ebp + 1e3: 53 push %ebx + 1e4: 83 ec 14 sub $0x14,%esp + 1e7: 8b 5d 08 mov 0x8(%ebp),%ebx + if (cmd == 0) { + 1ea: 85 db test %ebx,%ebx + 1ec: 74 42 je 230 + switch (cmd->type) { + 1ee: 83 3b 05 cmpl $0x5,(%ebx) + 1f1: 0f 87 e3 00 00 00 ja 2da + 1f7: 8b 03 mov (%ebx),%eax + 1f9: ff 24 85 a0 13 00 00 jmp *0x13a0(,%eax,4) + if (ecmd->argv[0] == 0) { + 200: 8b 43 04 mov 0x4(%ebx),%eax + 203: 85 c0 test %eax,%eax + 205: 74 29 je 230 + exec(ecmd->argv[0], ecmd->argv); + 207: 8d 53 04 lea 0x4(%ebx),%edx + 20a: 51 push %ecx + 20b: 51 push %ecx + 20c: 52 push %edx + 20d: 50 push %eax + 20e: e8 68 0c 00 00 call e7b + printf(2, "exec %s failed\n", ecmd->argv[0]); + 213: 83 c4 0c add $0xc,%esp + 216: ff 73 04 push 0x4(%ebx) + 219: 68 f7 12 00 00 push $0x12f7 + 21e: 6a 02 push $0x2 + 220: e8 9b 0d 00 00 call fc0 + break; + 225: 83 c4 10 add $0x10,%esp + 228: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 22f: 90 nop + exit(); + 230: e8 1e 0c 00 00 call e53 + if (fork1() == 0) { + 235: e8 86 ff ff ff call 1c0 + 23a: 85 c0 test %eax,%eax + 23c: 75 f2 jne 230 + 23e: e9 8c 00 00 00 jmp 2cf + if (pipe(p) < 0) { + 243: 83 ec 0c sub $0xc,%esp + 246: 8d 45 f0 lea -0x10(%ebp),%eax + 249: 50 push %eax + 24a: e8 14 0c 00 00 call e63 + 24f: 83 c4 10 add $0x10,%esp + 252: 85 c0 test %eax,%eax + 254: 0f 88 a2 00 00 00 js 2fc + if (fork1() == 0) { + 25a: e8 61 ff ff ff call 1c0 + 25f: 85 c0 test %eax,%eax + 261: 0f 84 a2 00 00 00 je 309 + if (fork1() == 0) { + 267: e8 54 ff ff ff call 1c0 + 26c: 85 c0 test %eax,%eax + 26e: 0f 84 c3 00 00 00 je 337 + close(p[0]); + 274: 83 ec 0c sub $0xc,%esp + 277: ff 75 f0 push -0x10(%ebp) + 27a: e8 6c 0c 00 00 call eeb + close(p[1]); + 27f: 58 pop %eax + 280: ff 75 f4 push -0xc(%ebp) + 283: e8 63 0c 00 00 call eeb + wait(); + 288: e8 ce 0b 00 00 call e5b + wait(); + 28d: e8 c9 0b 00 00 call e5b + break; + 292: 83 c4 10 add $0x10,%esp + 295: eb 99 jmp 230 + if (fork1() == 0) { + 297: e8 24 ff ff ff call 1c0 + 29c: 85 c0 test %eax,%eax + 29e: 74 2f je 2cf + wait(); + 2a0: e8 b6 0b 00 00 call e5b + runcmd(lcmd->right); + 2a5: 83 ec 0c sub $0xc,%esp + 2a8: ff 73 08 push 0x8(%ebx) + 2ab: e8 30 ff ff ff call 1e0 + close(rcmd->fd); + 2b0: 83 ec 0c sub $0xc,%esp + 2b3: ff 73 14 push 0x14(%ebx) + 2b6: e8 30 0c 00 00 call eeb + if (open(rcmd->file, rcmd->mode) < 0) { + 2bb: 58 pop %eax + 2bc: 5a pop %edx + 2bd: ff 73 10 push 0x10(%ebx) + 2c0: ff 73 08 push 0x8(%ebx) + 2c3: e8 f3 0b 00 00 call ebb + 2c8: 83 c4 10 add $0x10,%esp + 2cb: 85 c0 test %eax,%eax + 2cd: 78 18 js 2e7 + runcmd(bcmd->cmd); + 2cf: 83 ec 0c sub $0xc,%esp + 2d2: ff 73 04 push 0x4(%ebx) + 2d5: e8 06 ff ff ff call 1e0 + panic("runcmd"); + 2da: 83 ec 0c sub $0xc,%esp + 2dd: 68 f0 12 00 00 push $0x12f0 + 2e2: e8 b9 fe ff ff call 1a0 + printf(2, "open %s failed\n", rcmd->file); + 2e7: 51 push %ecx + 2e8: ff 73 08 push 0x8(%ebx) + 2eb: 68 07 13 00 00 push $0x1307 + 2f0: 6a 02 push $0x2 + 2f2: e8 c9 0c 00 00 call fc0 + exit(); + 2f7: e8 57 0b 00 00 call e53 + panic("pipe"); + 2fc: 83 ec 0c sub $0xc,%esp + 2ff: 68 17 13 00 00 push $0x1317 + 304: e8 97 fe ff ff call 1a0 + close(1); + 309: 83 ec 0c sub $0xc,%esp + 30c: 6a 01 push $0x1 + 30e: e8 d8 0b 00 00 call eeb + dup(p[1]); + 313: 58 pop %eax + 314: ff 75 f4 push -0xc(%ebp) + 317: e8 77 0b 00 00 call e93 + close(p[0]); + 31c: 58 pop %eax + 31d: ff 75 f0 push -0x10(%ebp) + 320: e8 c6 0b 00 00 call eeb + close(p[1]); + 325: 58 pop %eax + 326: ff 75 f4 push -0xc(%ebp) + 329: e8 bd 0b 00 00 call eeb + runcmd(pcmd->left); + 32e: 5a pop %edx + 32f: ff 73 04 push 0x4(%ebx) + 332: e8 a9 fe ff ff call 1e0 + close(0); + 337: 83 ec 0c sub $0xc,%esp + 33a: 6a 00 push $0x0 + 33c: e8 aa 0b 00 00 call eeb + dup(p[0]); + 341: 5a pop %edx + 342: ff 75 f0 push -0x10(%ebp) + 345: e8 49 0b 00 00 call e93 + close(p[0]); + 34a: 59 pop %ecx + 34b: ff 75 f0 push -0x10(%ebp) + 34e: e8 98 0b 00 00 call eeb + close(p[1]); + 353: 58 pop %eax + 354: ff 75 f4 push -0xc(%ebp) + 357: e8 8f 0b 00 00 call eeb + runcmd(pcmd->right); + 35c: 58 pop %eax + 35d: ff 73 08 push 0x8(%ebx) + 360: e8 7b fe ff ff call 1e0 + 365: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 36c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000370 : + + +// Constructors + +struct cmd* execcmd(void) { + 370: 55 push %ebp + 371: 89 e5 mov %esp,%ebp + 373: 53 push %ebx + 374: 83 ec 10 sub $0x10,%esp + struct execcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 377: 6a 54 push $0x54 + 379: e8 72 0e 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 37e: 83 c4 0c add $0xc,%esp + 381: 6a 54 push $0x54 + cmd = malloc(sizeof(*cmd)); + 383: 89 c3 mov %eax,%ebx + memset(cmd, 0, sizeof(*cmd)); + 385: 6a 00 push $0x0 + 387: 50 push %eax + 388: e8 33 09 00 00 call cc0 + cmd->type = EXEC; + 38d: c7 03 01 00 00 00 movl $0x1,(%ebx) + return (struct cmd*)cmd; +} + 393: 89 d8 mov %ebx,%eax + 395: 8b 5d fc mov -0x4(%ebp),%ebx + 398: c9 leave + 399: c3 ret + 39a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +000003a0 : + +struct cmd* redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd) { + 3a0: 55 push %ebp + 3a1: 89 e5 mov %esp,%ebp + 3a3: 53 push %ebx + 3a4: 83 ec 10 sub $0x10,%esp + struct redircmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 3a7: 6a 18 push $0x18 + 3a9: e8 42 0e 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 3ae: 83 c4 0c add $0xc,%esp + 3b1: 6a 18 push $0x18 + cmd = malloc(sizeof(*cmd)); + 3b3: 89 c3 mov %eax,%ebx + memset(cmd, 0, sizeof(*cmd)); + 3b5: 6a 00 push $0x0 + 3b7: 50 push %eax + 3b8: e8 03 09 00 00 call cc0 + cmd->type = REDIR; + cmd->cmd = subcmd; + 3bd: 8b 45 08 mov 0x8(%ebp),%eax + cmd->type = REDIR; + 3c0: c7 03 02 00 00 00 movl $0x2,(%ebx) + cmd->cmd = subcmd; + 3c6: 89 43 04 mov %eax,0x4(%ebx) + cmd->file = file; + 3c9: 8b 45 0c mov 0xc(%ebp),%eax + 3cc: 89 43 08 mov %eax,0x8(%ebx) + cmd->efile = efile; + 3cf: 8b 45 10 mov 0x10(%ebp),%eax + 3d2: 89 43 0c mov %eax,0xc(%ebx) + cmd->mode = mode; + 3d5: 8b 45 14 mov 0x14(%ebp),%eax + 3d8: 89 43 10 mov %eax,0x10(%ebx) + cmd->fd = fd; + 3db: 8b 45 18 mov 0x18(%ebp),%eax + 3de: 89 43 14 mov %eax,0x14(%ebx) + return (struct cmd*)cmd; +} + 3e1: 89 d8 mov %ebx,%eax + 3e3: 8b 5d fc mov -0x4(%ebp),%ebx + 3e6: c9 leave + 3e7: c3 ret + 3e8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3ef: 90 nop + +000003f0 : + +struct cmd* pipecmd(struct cmd *left, struct cmd *right) { + 3f0: 55 push %ebp + 3f1: 89 e5 mov %esp,%ebp + 3f3: 53 push %ebx + 3f4: 83 ec 10 sub $0x10,%esp + struct pipecmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 3f7: 6a 0c push $0xc + 3f9: e8 f2 0d 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 3fe: 83 c4 0c add $0xc,%esp + 401: 6a 0c push $0xc + cmd = malloc(sizeof(*cmd)); + 403: 89 c3 mov %eax,%ebx + memset(cmd, 0, sizeof(*cmd)); + 405: 6a 00 push $0x0 + 407: 50 push %eax + 408: e8 b3 08 00 00 call cc0 + cmd->type = PIPE; + cmd->left = left; + 40d: 8b 45 08 mov 0x8(%ebp),%eax + cmd->type = PIPE; + 410: c7 03 03 00 00 00 movl $0x3,(%ebx) + cmd->left = left; + 416: 89 43 04 mov %eax,0x4(%ebx) + cmd->right = right; + 419: 8b 45 0c mov 0xc(%ebp),%eax + 41c: 89 43 08 mov %eax,0x8(%ebx) + return (struct cmd*)cmd; +} + 41f: 89 d8 mov %ebx,%eax + 421: 8b 5d fc mov -0x4(%ebp),%ebx + 424: c9 leave + 425: c3 ret + 426: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 42d: 8d 76 00 lea 0x0(%esi),%esi + +00000430 : + +struct cmd* listcmd(struct cmd *left, struct cmd *right) { + 430: 55 push %ebp + 431: 89 e5 mov %esp,%ebp + 433: 53 push %ebx + 434: 83 ec 10 sub $0x10,%esp + struct listcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 437: 6a 0c push $0xc + 439: e8 b2 0d 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 43e: 83 c4 0c add $0xc,%esp + 441: 6a 0c push $0xc + cmd = malloc(sizeof(*cmd)); + 443: 89 c3 mov %eax,%ebx + memset(cmd, 0, sizeof(*cmd)); + 445: 6a 00 push $0x0 + 447: 50 push %eax + 448: e8 73 08 00 00 call cc0 + cmd->type = LIST; + cmd->left = left; + 44d: 8b 45 08 mov 0x8(%ebp),%eax + cmd->type = LIST; + 450: c7 03 04 00 00 00 movl $0x4,(%ebx) + cmd->left = left; + 456: 89 43 04 mov %eax,0x4(%ebx) + cmd->right = right; + 459: 8b 45 0c mov 0xc(%ebp),%eax + 45c: 89 43 08 mov %eax,0x8(%ebx) + return (struct cmd*)cmd; +} + 45f: 89 d8 mov %ebx,%eax + 461: 8b 5d fc mov -0x4(%ebp),%ebx + 464: c9 leave + 465: c3 ret + 466: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 46d: 8d 76 00 lea 0x0(%esi),%esi + +00000470 : + +struct cmd* backcmd(struct cmd *subcmd) { + 470: 55 push %ebp + 471: 89 e5 mov %esp,%ebp + 473: 53 push %ebx + 474: 83 ec 10 sub $0x10,%esp + struct backcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 477: 6a 08 push $0x8 + 479: e8 72 0d 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 47e: 83 c4 0c add $0xc,%esp + 481: 6a 08 push $0x8 + cmd = malloc(sizeof(*cmd)); + 483: 89 c3 mov %eax,%ebx + memset(cmd, 0, sizeof(*cmd)); + 485: 6a 00 push $0x0 + 487: 50 push %eax + 488: e8 33 08 00 00 call cc0 + cmd->type = BACK; + cmd->cmd = subcmd; + 48d: 8b 45 08 mov 0x8(%ebp),%eax + cmd->type = BACK; + 490: c7 03 05 00 00 00 movl $0x5,(%ebx) + cmd->cmd = subcmd; + 496: 89 43 04 mov %eax,0x4(%ebx) + return (struct cmd*)cmd; +} + 499: 89 d8 mov %ebx,%eax + 49b: 8b 5d fc mov -0x4(%ebp),%ebx + 49e: c9 leave + 49f: c3 ret + +000004a0 : +// Parsing + +char whitespace[] = " \t\r\n\v"; +char symbols[] = "<|>&;()"; + +int gettoken(char **ps, char *es, char **q, char **eq) { + 4a0: 55 push %ebp + 4a1: 89 e5 mov %esp,%ebp + 4a3: 57 push %edi + 4a4: 56 push %esi + 4a5: 53 push %ebx + 4a6: 83 ec 0c sub $0xc,%esp + char *s; + int ret; + + s = *ps; + 4a9: 8b 45 08 mov 0x8(%ebp),%eax +int gettoken(char **ps, char *es, char **q, char **eq) { + 4ac: 8b 5d 0c mov 0xc(%ebp),%ebx + 4af: 8b 75 10 mov 0x10(%ebp),%esi + s = *ps; + 4b2: 8b 38 mov (%eax),%edi + while (s < es && strchr(whitespace, *s)) { + 4b4: 39 df cmp %ebx,%edi + 4b6: 72 0f jb 4c7 + 4b8: eb 25 jmp 4df + 4ba: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + s++; + 4c0: 83 c7 01 add $0x1,%edi + while (s < es && strchr(whitespace, *s)) { + 4c3: 39 fb cmp %edi,%ebx + 4c5: 74 18 je 4df + 4c7: 0f be 07 movsbl (%edi),%eax + 4ca: 83 ec 08 sub $0x8,%esp + 4cd: 50 push %eax + 4ce: 68 0c 1a 00 00 push $0x1a0c + 4d3: e8 08 08 00 00 call ce0 + 4d8: 83 c4 10 add $0x10,%esp + 4db: 85 c0 test %eax,%eax + 4dd: 75 e1 jne 4c0 + } + if (q) { + 4df: 85 f6 test %esi,%esi + 4e1: 74 02 je 4e5 + *q = s; + 4e3: 89 3e mov %edi,(%esi) + } + ret = *s; + 4e5: 0f b6 07 movzbl (%edi),%eax + switch (*s) { + 4e8: 3c 3c cmp $0x3c,%al + 4ea: 0f 8f d0 00 00 00 jg 5c0 + 4f0: 3c 3a cmp $0x3a,%al + 4f2: 0f 8f b4 00 00 00 jg 5ac + 4f8: 84 c0 test %al,%al + 4fa: 75 44 jne 540 + 4fc: 31 f6 xor %esi,%esi + while (s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) { + s++; + } + break; + } + if (eq) { + 4fe: 8b 55 14 mov 0x14(%ebp),%edx + 501: 85 d2 test %edx,%edx + 503: 74 05 je 50a + *eq = s; + 505: 8b 45 14 mov 0x14(%ebp),%eax + 508: 89 38 mov %edi,(%eax) + } + + while (s < es && strchr(whitespace, *s)) { + 50a: 39 df cmp %ebx,%edi + 50c: 72 09 jb 517 + 50e: eb 1f jmp 52f + s++; + 510: 83 c7 01 add $0x1,%edi + while (s < es && strchr(whitespace, *s)) { + 513: 39 fb cmp %edi,%ebx + 515: 74 18 je 52f + 517: 0f be 07 movsbl (%edi),%eax + 51a: 83 ec 08 sub $0x8,%esp + 51d: 50 push %eax + 51e: 68 0c 1a 00 00 push $0x1a0c + 523: e8 b8 07 00 00 call ce0 + 528: 83 c4 10 add $0x10,%esp + 52b: 85 c0 test %eax,%eax + 52d: 75 e1 jne 510 + } + *ps = s; + 52f: 8b 45 08 mov 0x8(%ebp),%eax + 532: 89 38 mov %edi,(%eax) + return ret; +} + 534: 8d 65 f4 lea -0xc(%ebp),%esp + 537: 89 f0 mov %esi,%eax + 539: 5b pop %ebx + 53a: 5e pop %esi + 53b: 5f pop %edi + 53c: 5d pop %ebp + 53d: c3 ret + 53e: 66 90 xchg %ax,%ax + switch (*s) { + 540: 79 5e jns 5a0 + while (s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) { + 542: 39 fb cmp %edi,%ebx + 544: 77 34 ja 57a + if (eq) { + 546: 8b 45 14 mov 0x14(%ebp),%eax + 549: be 61 00 00 00 mov $0x61,%esi + 54e: 85 c0 test %eax,%eax + 550: 75 b3 jne 505 + 552: eb db jmp 52f + 554: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while (s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) { + 558: 0f be 07 movsbl (%edi),%eax + 55b: 83 ec 08 sub $0x8,%esp + 55e: 50 push %eax + 55f: 68 04 1a 00 00 push $0x1a04 + 564: e8 77 07 00 00 call ce0 + 569: 83 c4 10 add $0x10,%esp + 56c: 85 c0 test %eax,%eax + 56e: 75 22 jne 592 + s++; + 570: 83 c7 01 add $0x1,%edi + while (s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) { + 573: 39 fb cmp %edi,%ebx + 575: 74 cf je 546 + 577: 0f b6 07 movzbl (%edi),%eax + 57a: 83 ec 08 sub $0x8,%esp + 57d: 0f be f0 movsbl %al,%esi + 580: 56 push %esi + 581: 68 0c 1a 00 00 push $0x1a0c + 586: e8 55 07 00 00 call ce0 + 58b: 83 c4 10 add $0x10,%esp + 58e: 85 c0 test %eax,%eax + 590: 74 c6 je 558 + ret = 'a'; + 592: be 61 00 00 00 mov $0x61,%esi + 597: e9 62 ff ff ff jmp 4fe + 59c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + switch (*s) { + 5a0: 3c 26 cmp $0x26,%al + 5a2: 74 08 je 5ac + 5a4: 8d 48 d8 lea -0x28(%eax),%ecx + 5a7: 80 f9 01 cmp $0x1,%cl + 5aa: 77 96 ja 542 + ret = *s; + 5ac: 0f be f0 movsbl %al,%esi + s++; + 5af: 83 c7 01 add $0x1,%edi + break; + 5b2: e9 47 ff ff ff jmp 4fe + 5b7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5be: 66 90 xchg %ax,%ax + switch (*s) { + 5c0: 3c 3e cmp $0x3e,%al + 5c2: 75 1c jne 5e0 + if (*s == '>') { + 5c4: 80 7f 01 3e cmpb $0x3e,0x1(%edi) + s++; + 5c8: 8d 47 01 lea 0x1(%edi),%eax + if (*s == '>') { + 5cb: 74 1c je 5e9 + s++; + 5cd: 89 c7 mov %eax,%edi + 5cf: be 3e 00 00 00 mov $0x3e,%esi + 5d4: e9 25 ff ff ff jmp 4fe + 5d9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + switch (*s) { + 5e0: 3c 7c cmp $0x7c,%al + 5e2: 74 c8 je 5ac + 5e4: e9 59 ff ff ff jmp 542 + s++; + 5e9: 83 c7 02 add $0x2,%edi + ret = '+'; + 5ec: be 2b 00 00 00 mov $0x2b,%esi + 5f1: e9 08 ff ff ff jmp 4fe + 5f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5fd: 8d 76 00 lea 0x0(%esi),%esi + +00000600 : + +int peek(char **ps, char *es, char *toks) { + 600: 55 push %ebp + 601: 89 e5 mov %esp,%ebp + 603: 57 push %edi + 604: 56 push %esi + 605: 53 push %ebx + 606: 83 ec 0c sub $0xc,%esp + 609: 8b 7d 08 mov 0x8(%ebp),%edi + 60c: 8b 75 0c mov 0xc(%ebp),%esi + char *s; + + s = *ps; + 60f: 8b 1f mov (%edi),%ebx + while (s < es && strchr(whitespace, *s)) { + 611: 39 f3 cmp %esi,%ebx + 613: 72 12 jb 627 + 615: eb 28 jmp 63f + 617: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 61e: 66 90 xchg %ax,%ax + s++; + 620: 83 c3 01 add $0x1,%ebx + while (s < es && strchr(whitespace, *s)) { + 623: 39 de cmp %ebx,%esi + 625: 74 18 je 63f + 627: 0f be 03 movsbl (%ebx),%eax + 62a: 83 ec 08 sub $0x8,%esp + 62d: 50 push %eax + 62e: 68 0c 1a 00 00 push $0x1a0c + 633: e8 a8 06 00 00 call ce0 + 638: 83 c4 10 add $0x10,%esp + 63b: 85 c0 test %eax,%eax + 63d: 75 e1 jne 620 + } + *ps = s; + 63f: 89 1f mov %ebx,(%edi) + return *s && strchr(toks, *s); + 641: 0f be 03 movsbl (%ebx),%eax + 644: 31 d2 xor %edx,%edx + 646: 84 c0 test %al,%al + 648: 75 0e jne 658 +} + 64a: 8d 65 f4 lea -0xc(%ebp),%esp + 64d: 89 d0 mov %edx,%eax + 64f: 5b pop %ebx + 650: 5e pop %esi + 651: 5f pop %edi + 652: 5d pop %ebp + 653: c3 ret + 654: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + return *s && strchr(toks, *s); + 658: 83 ec 08 sub $0x8,%esp + 65b: 50 push %eax + 65c: ff 75 10 push 0x10(%ebp) + 65f: e8 7c 06 00 00 call ce0 + 664: 83 c4 10 add $0x10,%esp + 667: 31 d2 xor %edx,%edx + 669: 85 c0 test %eax,%eax + 66b: 0f 95 c2 setne %dl +} + 66e: 8d 65 f4 lea -0xc(%ebp),%esp + 671: 5b pop %ebx + 672: 89 d0 mov %edx,%eax + 674: 5e pop %esi + 675: 5f pop %edi + 676: 5d pop %ebp + 677: c3 ret + 678: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 67f: 90 nop + +00000680 : + cmd = pipecmd(cmd, parsepipe(ps, es)); + } + return cmd; +} + +struct cmd* parseredirs(struct cmd *cmd, char **ps, char *es) { + 680: 55 push %ebp + 681: 89 e5 mov %esp,%ebp + 683: 57 push %edi + 684: 56 push %esi + 685: 53 push %ebx + 686: 83 ec 2c sub $0x2c,%esp + 689: 8b 75 0c mov 0xc(%ebp),%esi + 68c: 8b 5d 10 mov 0x10(%ebp),%ebx + int tok; + char *q, *eq; + + while (peek(ps, es, "<>")) { + 68f: 90 nop + 690: 83 ec 04 sub $0x4,%esp + 693: 68 39 13 00 00 push $0x1339 + 698: 53 push %ebx + 699: 56 push %esi + 69a: e8 61 ff ff ff call 600 + 69f: 83 c4 10 add $0x10,%esp + 6a2: 85 c0 test %eax,%eax + 6a4: 0f 84 f6 00 00 00 je 7a0 + tok = gettoken(ps, es, 0, 0); + 6aa: 6a 00 push $0x0 + 6ac: 6a 00 push $0x0 + 6ae: 53 push %ebx + 6af: 56 push %esi + 6b0: e8 eb fd ff ff call 4a0 + 6b5: 89 c7 mov %eax,%edi + if (gettoken(ps, es, &q, &eq) != 'a') { + 6b7: 8d 45 e4 lea -0x1c(%ebp),%eax + 6ba: 50 push %eax + 6bb: 8d 45 e0 lea -0x20(%ebp),%eax + 6be: 50 push %eax + 6bf: 53 push %ebx + 6c0: 56 push %esi + 6c1: e8 da fd ff ff call 4a0 + 6c6: 83 c4 20 add $0x20,%esp + 6c9: 83 f8 61 cmp $0x61,%eax + 6cc: 0f 85 d9 00 00 00 jne 7ab + panic("missing file for redirection"); + } + switch (tok) { + 6d2: 83 ff 3c cmp $0x3c,%edi + 6d5: 74 69 je 740 + 6d7: 83 ff 3e cmp $0x3e,%edi + 6da: 74 05 je 6e1 + 6dc: 83 ff 2b cmp $0x2b,%edi + 6df: 75 af jne 690 + cmd = malloc(sizeof(*cmd)); + 6e1: 83 ec 0c sub $0xc,%esp + break; + case '>': + cmd = redircmd(cmd, q, eq, O_WRONLY | O_CREATE, 1); + break; + case '+': // >> + cmd = redircmd(cmd, q, eq, O_WRONLY | O_CREATE, 1); + 6e4: 8b 55 e4 mov -0x1c(%ebp),%edx + 6e7: 8b 4d e0 mov -0x20(%ebp),%ecx + cmd = malloc(sizeof(*cmd)); + 6ea: 6a 18 push $0x18 + cmd = redircmd(cmd, q, eq, O_WRONLY | O_CREATE, 1); + 6ec: 89 55 d0 mov %edx,-0x30(%ebp) + 6ef: 89 4d d4 mov %ecx,-0x2c(%ebp) + cmd = malloc(sizeof(*cmd)); + 6f2: e8 f9 0a 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 6f7: 83 c4 0c add $0xc,%esp + 6fa: 6a 18 push $0x18 + cmd = malloc(sizeof(*cmd)); + 6fc: 89 c7 mov %eax,%edi + memset(cmd, 0, sizeof(*cmd)); + 6fe: 6a 00 push $0x0 + 700: 50 push %eax + 701: e8 ba 05 00 00 call cc0 + cmd->type = REDIR; + 706: c7 07 02 00 00 00 movl $0x2,(%edi) + cmd->cmd = subcmd; + 70c: 8b 45 08 mov 0x8(%ebp),%eax + break; + 70f: 83 c4 10 add $0x10,%esp + cmd->cmd = subcmd; + 712: 89 47 04 mov %eax,0x4(%edi) + cmd->file = file; + 715: 8b 4d d4 mov -0x2c(%ebp),%ecx + 718: 89 4f 08 mov %ecx,0x8(%edi) + cmd->efile = efile; + 71b: 8b 55 d0 mov -0x30(%ebp),%edx + cmd->mode = mode; + 71e: c7 47 10 01 02 00 00 movl $0x201,0x10(%edi) + cmd->efile = efile; + 725: 89 57 0c mov %edx,0xc(%edi) + cmd->fd = fd; + 728: c7 47 14 01 00 00 00 movl $0x1,0x14(%edi) + break; + 72f: 89 7d 08 mov %edi,0x8(%ebp) + 732: e9 59 ff ff ff jmp 690 + 737: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 73e: 66 90 xchg %ax,%ax + cmd = malloc(sizeof(*cmd)); + 740: 83 ec 0c sub $0xc,%esp + cmd = redircmd(cmd, q, eq, O_RDONLY, 0); + 743: 8b 55 e4 mov -0x1c(%ebp),%edx + 746: 8b 4d e0 mov -0x20(%ebp),%ecx + cmd = malloc(sizeof(*cmd)); + 749: 6a 18 push $0x18 + cmd = redircmd(cmd, q, eq, O_RDONLY, 0); + 74b: 89 55 d0 mov %edx,-0x30(%ebp) + 74e: 89 4d d4 mov %ecx,-0x2c(%ebp) + cmd = malloc(sizeof(*cmd)); + 751: e8 9a 0a 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 756: 83 c4 0c add $0xc,%esp + 759: 6a 18 push $0x18 + cmd = malloc(sizeof(*cmd)); + 75b: 89 c7 mov %eax,%edi + memset(cmd, 0, sizeof(*cmd)); + 75d: 6a 00 push $0x0 + 75f: 50 push %eax + 760: e8 5b 05 00 00 call cc0 + cmd->cmd = subcmd; + 765: 8b 45 08 mov 0x8(%ebp),%eax + cmd->file = file; + 768: 8b 4d d4 mov -0x2c(%ebp),%ecx + break; + 76b: 89 7d 08 mov %edi,0x8(%ebp) + cmd->efile = efile; + 76e: 8b 55 d0 mov -0x30(%ebp),%edx + cmd->type = REDIR; + 771: c7 07 02 00 00 00 movl $0x2,(%edi) + break; + 777: 83 c4 10 add $0x10,%esp + cmd->cmd = subcmd; + 77a: 89 47 04 mov %eax,0x4(%edi) + cmd->file = file; + 77d: 89 4f 08 mov %ecx,0x8(%edi) + cmd->efile = efile; + 780: 89 57 0c mov %edx,0xc(%edi) + cmd->mode = mode; + 783: c7 47 10 00 00 00 00 movl $0x0,0x10(%edi) + cmd->fd = fd; + 78a: c7 47 14 00 00 00 00 movl $0x0,0x14(%edi) + break; + 791: e9 fa fe ff ff jmp 690 + 796: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 79d: 8d 76 00 lea 0x0(%esi),%esi + } + } + return cmd; +} + 7a0: 8b 45 08 mov 0x8(%ebp),%eax + 7a3: 8d 65 f4 lea -0xc(%ebp),%esp + 7a6: 5b pop %ebx + 7a7: 5e pop %esi + 7a8: 5f pop %edi + 7a9: 5d pop %ebp + 7aa: c3 ret + panic("missing file for redirection"); + 7ab: 83 ec 0c sub $0xc,%esp + 7ae: 68 1c 13 00 00 push $0x131c + 7b3: e8 e8 f9 ff ff call 1a0 + 7b8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 7bf: 90 nop + +000007c0 : + gettoken(ps, es, 0, 0); + cmd = parseredirs(cmd, ps, es); + return cmd; +} + +struct cmd* parseexec(char **ps, char *es) { + 7c0: 55 push %ebp + 7c1: 89 e5 mov %esp,%ebp + 7c3: 57 push %edi + 7c4: 56 push %esi + 7c5: 53 push %ebx + 7c6: 83 ec 30 sub $0x30,%esp + 7c9: 8b 75 08 mov 0x8(%ebp),%esi + 7cc: 8b 7d 0c mov 0xc(%ebp),%edi + char *q, *eq; + int tok, argc; + struct execcmd *cmd; + struct cmd *ret; + + if (peek(ps, es, "(")) { + 7cf: 68 3c 13 00 00 push $0x133c + 7d4: 57 push %edi + 7d5: 56 push %esi + 7d6: e8 25 fe ff ff call 600 + 7db: 83 c4 10 add $0x10,%esp + 7de: 85 c0 test %eax,%eax + 7e0: 0f 85 aa 00 00 00 jne 890 + cmd = malloc(sizeof(*cmd)); + 7e6: 83 ec 0c sub $0xc,%esp + 7e9: 89 c3 mov %eax,%ebx + 7eb: 6a 54 push $0x54 + 7ed: e8 fe 09 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 7f2: 83 c4 0c add $0xc,%esp + 7f5: 6a 54 push $0x54 + 7f7: 6a 00 push $0x0 + 7f9: 50 push %eax + 7fa: 89 45 d0 mov %eax,-0x30(%ebp) + 7fd: e8 be 04 00 00 call cc0 + cmd->type = EXEC; + 802: 8b 45 d0 mov -0x30(%ebp),%eax + + ret = execcmd(); + cmd = (struct execcmd*)ret; + + argc = 0; + ret = parseredirs(ret, ps, es); + 805: 83 c4 0c add $0xc,%esp + cmd->type = EXEC; + 808: c7 00 01 00 00 00 movl $0x1,(%eax) + ret = parseredirs(ret, ps, es); + 80e: 57 push %edi + 80f: 56 push %esi + 810: 50 push %eax + 811: e8 6a fe ff ff call 680 + while (!peek(ps, es, "|)&;")) { + 816: 83 c4 10 add $0x10,%esp + ret = parseredirs(ret, ps, es); + 819: 89 45 d4 mov %eax,-0x2c(%ebp) + while (!peek(ps, es, "|)&;")) { + 81c: eb 15 jmp 833 + 81e: 66 90 xchg %ax,%ax + cmd->eargv[argc] = eq; + argc++; + if (argc >= MAXARGS) { + panic("too many args"); + } + ret = parseredirs(ret, ps, es); + 820: 83 ec 04 sub $0x4,%esp + 823: 57 push %edi + 824: 56 push %esi + 825: ff 75 d4 push -0x2c(%ebp) + 828: e8 53 fe ff ff call 680 + 82d: 83 c4 10 add $0x10,%esp + 830: 89 45 d4 mov %eax,-0x2c(%ebp) + while (!peek(ps, es, "|)&;")) { + 833: 83 ec 04 sub $0x4,%esp + 836: 68 53 13 00 00 push $0x1353 + 83b: 57 push %edi + 83c: 56 push %esi + 83d: e8 be fd ff ff call 600 + 842: 83 c4 10 add $0x10,%esp + 845: 85 c0 test %eax,%eax + 847: 75 5f jne 8a8 + if ((tok = gettoken(ps, es, &q, &eq)) == 0) { + 849: 8d 45 e4 lea -0x1c(%ebp),%eax + 84c: 50 push %eax + 84d: 8d 45 e0 lea -0x20(%ebp),%eax + 850: 50 push %eax + 851: 57 push %edi + 852: 56 push %esi + 853: e8 48 fc ff ff call 4a0 + 858: 83 c4 10 add $0x10,%esp + 85b: 85 c0 test %eax,%eax + 85d: 74 49 je 8a8 + if (tok != 'a') { + 85f: 83 f8 61 cmp $0x61,%eax + 862: 75 62 jne 8c6 + cmd->argv[argc] = q; + 864: 8b 45 e0 mov -0x20(%ebp),%eax + 867: 8b 55 d0 mov -0x30(%ebp),%edx + 86a: 89 44 9a 04 mov %eax,0x4(%edx,%ebx,4) + cmd->eargv[argc] = eq; + 86e: 8b 45 e4 mov -0x1c(%ebp),%eax + 871: 89 44 9a 2c mov %eax,0x2c(%edx,%ebx,4) + argc++; + 875: 83 c3 01 add $0x1,%ebx + if (argc >= MAXARGS) { + 878: 83 fb 0a cmp $0xa,%ebx + 87b: 75 a3 jne 820 + panic("too many args"); + 87d: 83 ec 0c sub $0xc,%esp + 880: 68 45 13 00 00 push $0x1345 + 885: e8 16 f9 ff ff call 1a0 + 88a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + return parseblock(ps, es); + 890: 89 7d 0c mov %edi,0xc(%ebp) + 893: 89 75 08 mov %esi,0x8(%ebp) + } + cmd->argv[argc] = 0; + cmd->eargv[argc] = 0; + return ret; +} + 896: 8d 65 f4 lea -0xc(%ebp),%esp + 899: 5b pop %ebx + 89a: 5e pop %esi + 89b: 5f pop %edi + 89c: 5d pop %ebp + return parseblock(ps, es); + 89d: e9 ae 01 00 00 jmp a50 + 8a2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + cmd->argv[argc] = 0; + 8a8: 8b 45 d0 mov -0x30(%ebp),%eax + 8ab: c7 44 98 04 00 00 00 movl $0x0,0x4(%eax,%ebx,4) + 8b2: 00 + cmd->eargv[argc] = 0; + 8b3: c7 44 98 2c 00 00 00 movl $0x0,0x2c(%eax,%ebx,4) + 8ba: 00 +} + 8bb: 8b 45 d4 mov -0x2c(%ebp),%eax + 8be: 8d 65 f4 lea -0xc(%ebp),%esp + 8c1: 5b pop %ebx + 8c2: 5e pop %esi + 8c3: 5f pop %edi + 8c4: 5d pop %ebp + 8c5: c3 ret + panic("syntax"); + 8c6: 83 ec 0c sub $0xc,%esp + 8c9: 68 3e 13 00 00 push $0x133e + 8ce: e8 cd f8 ff ff call 1a0 + 8d3: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 8da: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +000008e0 : +struct cmd* parsepipe(char **ps, char *es) { + 8e0: 55 push %ebp + 8e1: 89 e5 mov %esp,%ebp + 8e3: 57 push %edi + 8e4: 56 push %esi + 8e5: 53 push %ebx + 8e6: 83 ec 14 sub $0x14,%esp + 8e9: 8b 75 08 mov 0x8(%ebp),%esi + 8ec: 8b 7d 0c mov 0xc(%ebp),%edi + cmd = parseexec(ps, es); + 8ef: 57 push %edi + 8f0: 56 push %esi + 8f1: e8 ca fe ff ff call 7c0 + if (peek(ps, es, "|")) { + 8f6: 83 c4 0c add $0xc,%esp + 8f9: 68 58 13 00 00 push $0x1358 + cmd = parseexec(ps, es); + 8fe: 89 c3 mov %eax,%ebx + if (peek(ps, es, "|")) { + 900: 57 push %edi + 901: 56 push %esi + 902: e8 f9 fc ff ff call 600 + 907: 83 c4 10 add $0x10,%esp + 90a: 85 c0 test %eax,%eax + 90c: 75 12 jne 920 +} + 90e: 8d 65 f4 lea -0xc(%ebp),%esp + 911: 89 d8 mov %ebx,%eax + 913: 5b pop %ebx + 914: 5e pop %esi + 915: 5f pop %edi + 916: 5d pop %ebp + 917: c3 ret + 918: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 91f: 90 nop + gettoken(ps, es, 0, 0); + 920: 6a 00 push $0x0 + 922: 6a 00 push $0x0 + 924: 57 push %edi + 925: 56 push %esi + 926: e8 75 fb ff ff call 4a0 + cmd = pipecmd(cmd, parsepipe(ps, es)); + 92b: 58 pop %eax + 92c: 5a pop %edx + 92d: 57 push %edi + 92e: 56 push %esi + 92f: e8 ac ff ff ff call 8e0 + cmd = malloc(sizeof(*cmd)); + 934: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + cmd = pipecmd(cmd, parsepipe(ps, es)); + 93b: 89 c7 mov %eax,%edi + cmd = malloc(sizeof(*cmd)); + 93d: e8 ae 08 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 942: 83 c4 0c add $0xc,%esp + 945: 6a 0c push $0xc + cmd = malloc(sizeof(*cmd)); + 947: 89 c6 mov %eax,%esi + memset(cmd, 0, sizeof(*cmd)); + 949: 6a 00 push $0x0 + 94b: 50 push %eax + 94c: e8 6f 03 00 00 call cc0 + cmd->left = left; + 951: 89 5e 04 mov %ebx,0x4(%esi) + cmd->right = right; + 954: 83 c4 10 add $0x10,%esp + 957: 89 f3 mov %esi,%ebx + cmd->type = PIPE; + 959: c7 06 03 00 00 00 movl $0x3,(%esi) +} + 95f: 89 d8 mov %ebx,%eax + cmd->right = right; + 961: 89 7e 08 mov %edi,0x8(%esi) +} + 964: 8d 65 f4 lea -0xc(%ebp),%esp + 967: 5b pop %ebx + 968: 5e pop %esi + 969: 5f pop %edi + 96a: 5d pop %ebp + 96b: c3 ret + 96c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000970 : +struct cmd* parseline(char **ps, char *es) { + 970: 55 push %ebp + 971: 89 e5 mov %esp,%ebp + 973: 57 push %edi + 974: 56 push %esi + 975: 53 push %ebx + 976: 83 ec 24 sub $0x24,%esp + 979: 8b 75 08 mov 0x8(%ebp),%esi + 97c: 8b 7d 0c mov 0xc(%ebp),%edi + cmd = parsepipe(ps, es); + 97f: 57 push %edi + 980: 56 push %esi + 981: e8 5a ff ff ff call 8e0 + while (peek(ps, es, "&")) { + 986: 83 c4 10 add $0x10,%esp + cmd = parsepipe(ps, es); + 989: 89 c3 mov %eax,%ebx + while (peek(ps, es, "&")) { + 98b: eb 3b jmp 9c8 + 98d: 8d 76 00 lea 0x0(%esi),%esi + gettoken(ps, es, 0, 0); + 990: 6a 00 push $0x0 + 992: 6a 00 push $0x0 + 994: 57 push %edi + 995: 56 push %esi + 996: e8 05 fb ff ff call 4a0 + cmd = malloc(sizeof(*cmd)); + 99b: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 9a2: e8 49 08 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + 9a7: 83 c4 0c add $0xc,%esp + 9aa: 6a 08 push $0x8 + 9ac: 6a 00 push $0x0 + 9ae: 50 push %eax + 9af: 89 45 e4 mov %eax,-0x1c(%ebp) + 9b2: e8 09 03 00 00 call cc0 + cmd->type = BACK; + 9b7: 8b 55 e4 mov -0x1c(%ebp),%edx + cmd->cmd = subcmd; + 9ba: 83 c4 10 add $0x10,%esp + cmd->type = BACK; + 9bd: c7 02 05 00 00 00 movl $0x5,(%edx) + cmd->cmd = subcmd; + 9c3: 89 5a 04 mov %ebx,0x4(%edx) + 9c6: 89 d3 mov %edx,%ebx + while (peek(ps, es, "&")) { + 9c8: 83 ec 04 sub $0x4,%esp + 9cb: 68 5a 13 00 00 push $0x135a + 9d0: 57 push %edi + 9d1: 56 push %esi + 9d2: e8 29 fc ff ff call 600 + 9d7: 83 c4 10 add $0x10,%esp + 9da: 85 c0 test %eax,%eax + 9dc: 75 b2 jne 990 + if (peek(ps, es, ";")) { + 9de: 83 ec 04 sub $0x4,%esp + 9e1: 68 56 13 00 00 push $0x1356 + 9e6: 57 push %edi + 9e7: 56 push %esi + 9e8: e8 13 fc ff ff call 600 + 9ed: 83 c4 10 add $0x10,%esp + 9f0: 85 c0 test %eax,%eax + 9f2: 75 0c jne a00 +} + 9f4: 8d 65 f4 lea -0xc(%ebp),%esp + 9f7: 89 d8 mov %ebx,%eax + 9f9: 5b pop %ebx + 9fa: 5e pop %esi + 9fb: 5f pop %edi + 9fc: 5d pop %ebp + 9fd: c3 ret + 9fe: 66 90 xchg %ax,%ax + gettoken(ps, es, 0, 0); + a00: 6a 00 push $0x0 + a02: 6a 00 push $0x0 + a04: 57 push %edi + a05: 56 push %esi + a06: e8 95 fa ff ff call 4a0 + cmd = listcmd(cmd, parseline(ps, es)); + a0b: 58 pop %eax + a0c: 5a pop %edx + a0d: 57 push %edi + a0e: 56 push %esi + a0f: e8 5c ff ff ff call 970 + cmd = malloc(sizeof(*cmd)); + a14: c7 04 24 0c 00 00 00 movl $0xc,(%esp) + cmd = listcmd(cmd, parseline(ps, es)); + a1b: 89 c7 mov %eax,%edi + cmd = malloc(sizeof(*cmd)); + a1d: e8 ce 07 00 00 call 11f0 + memset(cmd, 0, sizeof(*cmd)); + a22: 83 c4 0c add $0xc,%esp + a25: 6a 0c push $0xc + cmd = malloc(sizeof(*cmd)); + a27: 89 c6 mov %eax,%esi + memset(cmd, 0, sizeof(*cmd)); + a29: 6a 00 push $0x0 + a2b: 50 push %eax + a2c: e8 8f 02 00 00 call cc0 + cmd->left = left; + a31: 89 5e 04 mov %ebx,0x4(%esi) + cmd->right = right; + a34: 83 c4 10 add $0x10,%esp + a37: 89 f3 mov %esi,%ebx + cmd->type = LIST; + a39: c7 06 04 00 00 00 movl $0x4,(%esi) +} + a3f: 89 d8 mov %ebx,%eax + cmd->right = right; + a41: 89 7e 08 mov %edi,0x8(%esi) +} + a44: 8d 65 f4 lea -0xc(%ebp),%esp + a47: 5b pop %ebx + a48: 5e pop %esi + a49: 5f pop %edi + a4a: 5d pop %ebp + a4b: c3 ret + a4c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000a50 : +struct cmd* parseblock(char **ps, char *es) { + a50: 55 push %ebp + a51: 89 e5 mov %esp,%ebp + a53: 57 push %edi + a54: 56 push %esi + a55: 53 push %ebx + a56: 83 ec 10 sub $0x10,%esp + a59: 8b 5d 08 mov 0x8(%ebp),%ebx + a5c: 8b 75 0c mov 0xc(%ebp),%esi + if (!peek(ps, es, "(")) { + a5f: 68 3c 13 00 00 push $0x133c + a64: 56 push %esi + a65: 53 push %ebx + a66: e8 95 fb ff ff call 600 + a6b: 83 c4 10 add $0x10,%esp + a6e: 85 c0 test %eax,%eax + a70: 74 4a je abc + gettoken(ps, es, 0, 0); + a72: 6a 00 push $0x0 + a74: 6a 00 push $0x0 + a76: 56 push %esi + a77: 53 push %ebx + a78: e8 23 fa ff ff call 4a0 + cmd = parseline(ps, es); + a7d: 58 pop %eax + a7e: 5a pop %edx + a7f: 56 push %esi + a80: 53 push %ebx + a81: e8 ea fe ff ff call 970 + if (!peek(ps, es, ")")) { + a86: 83 c4 0c add $0xc,%esp + a89: 68 78 13 00 00 push $0x1378 + cmd = parseline(ps, es); + a8e: 89 c7 mov %eax,%edi + if (!peek(ps, es, ")")) { + a90: 56 push %esi + a91: 53 push %ebx + a92: e8 69 fb ff ff call 600 + a97: 83 c4 10 add $0x10,%esp + a9a: 85 c0 test %eax,%eax + a9c: 74 2b je ac9 + gettoken(ps, es, 0, 0); + a9e: 6a 00 push $0x0 + aa0: 6a 00 push $0x0 + aa2: 56 push %esi + aa3: 53 push %ebx + aa4: e8 f7 f9 ff ff call 4a0 + cmd = parseredirs(cmd, ps, es); + aa9: 83 c4 0c add $0xc,%esp + aac: 56 push %esi + aad: 53 push %ebx + aae: 57 push %edi + aaf: e8 cc fb ff ff call 680 +} + ab4: 8d 65 f4 lea -0xc(%ebp),%esp + ab7: 5b pop %ebx + ab8: 5e pop %esi + ab9: 5f pop %edi + aba: 5d pop %ebp + abb: c3 ret + panic("parseblock"); + abc: 83 ec 0c sub $0xc,%esp + abf: 68 5c 13 00 00 push $0x135c + ac4: e8 d7 f6 ff ff call 1a0 + panic("syntax - missing )"); + ac9: 83 ec 0c sub $0xc,%esp + acc: 68 67 13 00 00 push $0x1367 + ad1: e8 ca f6 ff ff call 1a0 + ad6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + add: 8d 76 00 lea 0x0(%esi),%esi + +00000ae0 : + +// NUL-terminate all the counted strings. +struct cmd* nulterminate(struct cmd *cmd) { + ae0: 55 push %ebp + ae1: 89 e5 mov %esp,%ebp + ae3: 53 push %ebx + ae4: 83 ec 04 sub $0x4,%esp + ae7: 8b 5d 08 mov 0x8(%ebp),%ebx + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if (cmd == 0) { + aea: 85 db test %ebx,%ebx + aec: 0f 84 8e 00 00 00 je b80 + return 0; + } + + switch (cmd->type) { + af2: 83 3b 05 cmpl $0x5,(%ebx) + af5: 77 61 ja b58 + af7: 8b 03 mov (%ebx),%eax + af9: ff 24 85 b8 13 00 00 jmp *0x13b8(,%eax,4) + nulterminate(pcmd->right); + break; + + case LIST: + lcmd = (struct listcmd*)cmd; + nulterminate(lcmd->left); + b00: 83 ec 0c sub $0xc,%esp + b03: ff 73 04 push 0x4(%ebx) + b06: e8 d5 ff ff ff call ae0 + nulterminate(lcmd->right); + b0b: 58 pop %eax + b0c: ff 73 08 push 0x8(%ebx) + b0f: e8 cc ff ff ff call ae0 + break; + b14: 83 c4 10 add $0x10,%esp + b17: 89 d8 mov %ebx,%eax + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + break; + } + return cmd; +} + b19: 8b 5d fc mov -0x4(%ebp),%ebx + b1c: c9 leave + b1d: c3 ret + b1e: 66 90 xchg %ax,%ax + nulterminate(bcmd->cmd); + b20: 83 ec 0c sub $0xc,%esp + b23: ff 73 04 push 0x4(%ebx) + b26: e8 b5 ff ff ff call ae0 + break; + b2b: 89 d8 mov %ebx,%eax + b2d: 83 c4 10 add $0x10,%esp +} + b30: 8b 5d fc mov -0x4(%ebp),%ebx + b33: c9 leave + b34: c3 ret + b35: 8d 76 00 lea 0x0(%esi),%esi + for (i = 0; ecmd->argv[i]; i++) { + b38: 8b 4b 04 mov 0x4(%ebx),%ecx + b3b: 8d 43 08 lea 0x8(%ebx),%eax + b3e: 85 c9 test %ecx,%ecx + b40: 74 16 je b58 + b42: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + *ecmd->eargv[i] = 0; + b48: 8b 50 24 mov 0x24(%eax),%edx + for (i = 0; ecmd->argv[i]; i++) { + b4b: 83 c0 04 add $0x4,%eax + *ecmd->eargv[i] = 0; + b4e: c6 02 00 movb $0x0,(%edx) + for (i = 0; ecmd->argv[i]; i++) { + b51: 8b 50 fc mov -0x4(%eax),%edx + b54: 85 d2 test %edx,%edx + b56: 75 f0 jne b48 + switch (cmd->type) { + b58: 89 d8 mov %ebx,%eax +} + b5a: 8b 5d fc mov -0x4(%ebp),%ebx + b5d: c9 leave + b5e: c3 ret + b5f: 90 nop + nulterminate(rcmd->cmd); + b60: 83 ec 0c sub $0xc,%esp + b63: ff 73 04 push 0x4(%ebx) + b66: e8 75 ff ff ff call ae0 + *rcmd->efile = 0; + b6b: 8b 43 0c mov 0xc(%ebx),%eax + break; + b6e: 83 c4 10 add $0x10,%esp + *rcmd->efile = 0; + b71: c6 00 00 movb $0x0,(%eax) + break; + b74: 89 d8 mov %ebx,%eax +} + b76: 8b 5d fc mov -0x4(%ebp),%ebx + b79: c9 leave + b7a: c3 ret + b7b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + b7f: 90 nop + return 0; + b80: 31 c0 xor %eax,%eax + b82: eb 95 jmp b19 + b84: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + b8b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + b8f: 90 nop + +00000b90 : +struct cmd* parsecmd(char *s) { + b90: 55 push %ebp + b91: 89 e5 mov %esp,%ebp + b93: 57 push %edi + b94: 56 push %esi + cmd = parseline(&s, es); + b95: 8d 7d 08 lea 0x8(%ebp),%edi +struct cmd* parsecmd(char *s) { + b98: 53 push %ebx + b99: 83 ec 18 sub $0x18,%esp + es = s + strlen(s); + b9c: 8b 5d 08 mov 0x8(%ebp),%ebx + b9f: 53 push %ebx + ba0: e8 eb 00 00 00 call c90 + cmd = parseline(&s, es); + ba5: 59 pop %ecx + ba6: 5e pop %esi + es = s + strlen(s); + ba7: 01 c3 add %eax,%ebx + cmd = parseline(&s, es); + ba9: 53 push %ebx + baa: 57 push %edi + bab: e8 c0 fd ff ff call 970 + peek(&s, es, ""); + bb0: 83 c4 0c add $0xc,%esp + bb3: 68 06 13 00 00 push $0x1306 + cmd = parseline(&s, es); + bb8: 89 c6 mov %eax,%esi + peek(&s, es, ""); + bba: 53 push %ebx + bbb: 57 push %edi + bbc: e8 3f fa ff ff call 600 + if (s != es) { + bc1: 8b 45 08 mov 0x8(%ebp),%eax + bc4: 83 c4 10 add $0x10,%esp + bc7: 39 d8 cmp %ebx,%eax + bc9: 75 13 jne bde + nulterminate(cmd); + bcb: 83 ec 0c sub $0xc,%esp + bce: 56 push %esi + bcf: e8 0c ff ff ff call ae0 +} + bd4: 8d 65 f4 lea -0xc(%ebp),%esp + bd7: 89 f0 mov %esi,%eax + bd9: 5b pop %ebx + bda: 5e pop %esi + bdb: 5f pop %edi + bdc: 5d pop %ebp + bdd: c3 ret + printf(2, "leftovers: %s\n", s); + bde: 52 push %edx + bdf: 50 push %eax + be0: 68 7a 13 00 00 push $0x137a + be5: 6a 02 push $0x2 + be7: e8 d4 03 00 00 call fc0 + panic("syntax"); + bec: c7 04 24 3e 13 00 00 movl $0x133e,(%esp) + bf3: e8 a8 f5 ff ff call 1a0 + bf8: 66 90 xchg %ax,%ax + bfa: 66 90 xchg %ax,%ax + bfc: 66 90 xchg %ax,%ax + bfe: 66 90 xchg %ax,%ax + +00000c00 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + c00: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + c01: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + c03: 89 e5 mov %esp,%ebp + c05: 53 push %ebx + c06: 8b 4d 08 mov 0x8(%ebp),%ecx + c09: 8b 5d 0c mov 0xc(%ebp),%ebx + c0c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + c10: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + c14: 88 14 01 mov %dl,(%ecx,%eax,1) + c17: 83 c0 01 add $0x1,%eax + c1a: 84 d2 test %dl,%dl + c1c: 75 f2 jne c10 + ; + } + return os; +} + c1e: 8b 5d fc mov -0x4(%ebp),%ebx + c21: 89 c8 mov %ecx,%eax + c23: c9 leave + c24: c3 ret + c25: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + c2c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000c30 : + +int strcmp(const char *p, const char *q) { + c30: 55 push %ebp + c31: 89 e5 mov %esp,%ebp + c33: 53 push %ebx + c34: 8b 55 08 mov 0x8(%ebp),%edx + c37: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + c3a: 0f b6 02 movzbl (%edx),%eax + c3d: 84 c0 test %al,%al + c3f: 75 17 jne c58 + c41: eb 3a jmp c7d + c43: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + c47: 90 nop + c48: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + c4c: 83 c2 01 add $0x1,%edx + c4f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + c52: 84 c0 test %al,%al + c54: 74 1a je c70 + p++, q++; + c56: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + c58: 0f b6 19 movzbl (%ecx),%ebx + c5b: 38 c3 cmp %al,%bl + c5d: 74 e9 je c48 + } + return (uchar) * p - (uchar) * q; + c5f: 29 d8 sub %ebx,%eax +} + c61: 8b 5d fc mov -0x4(%ebp),%ebx + c64: c9 leave + c65: c3 ret + c66: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + c6d: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + c70: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + c74: 31 c0 xor %eax,%eax + c76: 29 d8 sub %ebx,%eax +} + c78: 8b 5d fc mov -0x4(%ebp),%ebx + c7b: c9 leave + c7c: c3 ret + return (uchar) * p - (uchar) * q; + c7d: 0f b6 19 movzbl (%ecx),%ebx + c80: 31 c0 xor %eax,%eax + c82: eb db jmp c5f + c84: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + c8b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + c8f: 90 nop + +00000c90 : + +uint strlen(const char *s) { + c90: 55 push %ebp + c91: 89 e5 mov %esp,%ebp + c93: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + c96: 80 3a 00 cmpb $0x0,(%edx) + c99: 74 15 je cb0 + c9b: 31 c0 xor %eax,%eax + c9d: 8d 76 00 lea 0x0(%esi),%esi + ca0: 83 c0 01 add $0x1,%eax + ca3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + ca7: 89 c1 mov %eax,%ecx + ca9: 75 f5 jne ca0 + ; + } + return n; +} + cab: 89 c8 mov %ecx,%eax + cad: 5d pop %ebp + cae: c3 ret + caf: 90 nop + for (n = 0; s[n]; n++) { + cb0: 31 c9 xor %ecx,%ecx +} + cb2: 5d pop %ebp + cb3: 89 c8 mov %ecx,%eax + cb5: c3 ret + cb6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + cbd: 8d 76 00 lea 0x0(%esi),%esi + +00000cc0 : + +void* memset(void *dst, int c, uint n) { + cc0: 55 push %ebp + cc1: 89 e5 mov %esp,%ebp + cc3: 57 push %edi + cc4: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + cc7: 8b 4d 10 mov 0x10(%ebp),%ecx + cca: 8b 45 0c mov 0xc(%ebp),%eax + ccd: 89 d7 mov %edx,%edi + ccf: fc cld + cd0: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + cd2: 8b 7d fc mov -0x4(%ebp),%edi + cd5: 89 d0 mov %edx,%eax + cd7: c9 leave + cd8: c3 ret + cd9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000ce0 : + +char* strchr(const char *s, char c) { + ce0: 55 push %ebp + ce1: 89 e5 mov %esp,%ebp + ce3: 8b 45 08 mov 0x8(%ebp),%eax + ce6: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + cea: 0f b6 10 movzbl (%eax),%edx + ced: 84 d2 test %dl,%dl + cef: 75 12 jne d03 + cf1: eb 1d jmp d10 + cf3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + cf7: 90 nop + cf8: 0f b6 50 01 movzbl 0x1(%eax),%edx + cfc: 83 c0 01 add $0x1,%eax + cff: 84 d2 test %dl,%dl + d01: 74 0d je d10 + if (*s == c) { + d03: 38 d1 cmp %dl,%cl + d05: 75 f1 jne cf8 + return (char*)s; + } + } + return 0; +} + d07: 5d pop %ebp + d08: c3 ret + d09: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + d10: 31 c0 xor %eax,%eax +} + d12: 5d pop %ebp + d13: c3 ret + d14: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + d1b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + d1f: 90 nop + +00000d20 : + +char* gets(char *buf, int max) { + d20: 55 push %ebp + d21: 89 e5 mov %esp,%ebp + d23: 57 push %edi + d24: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + d25: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + d28: 53 push %ebx + for (i = 0; i + 1 < max;) { + d29: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + d2b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + d2e: eb 27 jmp d57 + cc = read(0, &c, 1); + d30: 83 ec 04 sub $0x4,%esp + d33: 6a 01 push $0x1 + d35: 57 push %edi + d36: 6a 00 push $0x0 + d38: e8 2e 01 00 00 call e6b + if (cc < 1) { + d3d: 83 c4 10 add $0x10,%esp + d40: 85 c0 test %eax,%eax + d42: 7e 1d jle d61 + break; + } + buf[i++] = c; + d44: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + d48: 8b 55 08 mov 0x8(%ebp),%edx + d4b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + d4f: 3c 0a cmp $0xa,%al + d51: 74 1d je d70 + d53: 3c 0d cmp $0xd,%al + d55: 74 19 je d70 + for (i = 0; i + 1 < max;) { + d57: 89 de mov %ebx,%esi + d59: 83 c3 01 add $0x1,%ebx + d5c: 3b 5d 0c cmp 0xc(%ebp),%ebx + d5f: 7c cf jl d30 + break; + } + } + buf[i] = '\0'; + d61: 8b 45 08 mov 0x8(%ebp),%eax + d64: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + d68: 8d 65 f4 lea -0xc(%ebp),%esp + d6b: 5b pop %ebx + d6c: 5e pop %esi + d6d: 5f pop %edi + d6e: 5d pop %ebp + d6f: c3 ret + buf[i] = '\0'; + d70: 8b 45 08 mov 0x8(%ebp),%eax + d73: 89 de mov %ebx,%esi + d75: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + d79: 8d 65 f4 lea -0xc(%ebp),%esp + d7c: 5b pop %ebx + d7d: 5e pop %esi + d7e: 5f pop %edi + d7f: 5d pop %ebp + d80: c3 ret + d81: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + d88: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + d8f: 90 nop + +00000d90 : + +int stat(const char *n, struct stat *st) { + d90: 55 push %ebp + d91: 89 e5 mov %esp,%ebp + d93: 56 push %esi + d94: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + d95: 83 ec 08 sub $0x8,%esp + d98: 6a 00 push $0x0 + d9a: ff 75 08 push 0x8(%ebp) + d9d: e8 19 01 00 00 call ebb + if (fd < 0) { + da2: 83 c4 10 add $0x10,%esp + da5: 85 c0 test %eax,%eax + da7: 78 27 js dd0 + return -1; + } + r = fstat(fd, st); + da9: 83 ec 08 sub $0x8,%esp + dac: ff 75 0c push 0xc(%ebp) + daf: 89 c3 mov %eax,%ebx + db1: 50 push %eax + db2: e8 cc 00 00 00 call e83 + close(fd); + db7: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + dba: 89 c6 mov %eax,%esi + close(fd); + dbc: e8 2a 01 00 00 call eeb + return r; + dc1: 83 c4 10 add $0x10,%esp +} + dc4: 8d 65 f8 lea -0x8(%ebp),%esp + dc7: 89 f0 mov %esi,%eax + dc9: 5b pop %ebx + dca: 5e pop %esi + dcb: 5d pop %ebp + dcc: c3 ret + dcd: 8d 76 00 lea 0x0(%esi),%esi + return -1; + dd0: be ff ff ff ff mov $0xffffffff,%esi + dd5: eb ed jmp dc4 + dd7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + dde: 66 90 xchg %ax,%ax + +00000de0 : + +int atoi(const char *s) { + de0: 55 push %ebp + de1: 89 e5 mov %esp,%ebp + de3: 53 push %ebx + de4: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + de7: 0f be 02 movsbl (%edx),%eax + dea: 8d 48 d0 lea -0x30(%eax),%ecx + ded: 80 f9 09 cmp $0x9,%cl + n = 0; + df0: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + df5: 77 1e ja e15 + df7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + dfe: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + e00: 83 c2 01 add $0x1,%edx + e03: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + e06: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + e0a: 0f be 02 movsbl (%edx),%eax + e0d: 8d 58 d0 lea -0x30(%eax),%ebx + e10: 80 fb 09 cmp $0x9,%bl + e13: 76 eb jbe e00 + } + return n; +} + e15: 8b 5d fc mov -0x4(%ebp),%ebx + e18: 89 c8 mov %ecx,%eax + e1a: c9 leave + e1b: c3 ret + e1c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000e20 : + +void* memmove(void *vdst, const void *vsrc, int n) { + e20: 55 push %ebp + e21: 89 e5 mov %esp,%ebp + e23: 57 push %edi + e24: 8b 45 10 mov 0x10(%ebp),%eax + e27: 8b 55 08 mov 0x8(%ebp),%edx + e2a: 56 push %esi + e2b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + e2e: 85 c0 test %eax,%eax + e30: 7e 13 jle e45 + e32: 01 d0 add %edx,%eax + dst = vdst; + e34: 89 d7 mov %edx,%edi + e36: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + e3d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + e40: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + e41: 39 f8 cmp %edi,%eax + e43: 75 fb jne e40 + } + return vdst; +} + e45: 5e pop %esi + e46: 89 d0 mov %edx,%eax + e48: 5f pop %edi + e49: 5d pop %ebp + e4a: c3 ret + +00000e4b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + e4b: b8 01 00 00 00 mov $0x1,%eax + e50: cd 40 int $0x40 + e52: c3 ret + +00000e53 : +SYSCALL(exit) + e53: b8 02 00 00 00 mov $0x2,%eax + e58: cd 40 int $0x40 + e5a: c3 ret + +00000e5b : +SYSCALL(wait) + e5b: b8 03 00 00 00 mov $0x3,%eax + e60: cd 40 int $0x40 + e62: c3 ret + +00000e63 : +SYSCALL(pipe) + e63: b8 04 00 00 00 mov $0x4,%eax + e68: cd 40 int $0x40 + e6a: c3 ret + +00000e6b : +SYSCALL(read) + e6b: b8 05 00 00 00 mov $0x5,%eax + e70: cd 40 int $0x40 + e72: c3 ret + +00000e73 : +SYSCALL(kill) + e73: b8 06 00 00 00 mov $0x6,%eax + e78: cd 40 int $0x40 + e7a: c3 ret + +00000e7b : +SYSCALL(exec) + e7b: b8 07 00 00 00 mov $0x7,%eax + e80: cd 40 int $0x40 + e82: c3 ret + +00000e83 : +SYSCALL(fstat) + e83: b8 08 00 00 00 mov $0x8,%eax + e88: cd 40 int $0x40 + e8a: c3 ret + +00000e8b : +SYSCALL(chdir) + e8b: b8 09 00 00 00 mov $0x9,%eax + e90: cd 40 int $0x40 + e92: c3 ret + +00000e93 : +SYSCALL(dup) + e93: b8 0a 00 00 00 mov $0xa,%eax + e98: cd 40 int $0x40 + e9a: c3 ret + +00000e9b : +SYSCALL(getpid) + e9b: b8 0b 00 00 00 mov $0xb,%eax + ea0: cd 40 int $0x40 + ea2: c3 ret + +00000ea3 : +SYSCALL(sbrk) + ea3: b8 0c 00 00 00 mov $0xc,%eax + ea8: cd 40 int $0x40 + eaa: c3 ret + +00000eab : +SYSCALL(sleep) + eab: b8 0d 00 00 00 mov $0xd,%eax + eb0: cd 40 int $0x40 + eb2: c3 ret + +00000eb3 : +SYSCALL(uptime) + eb3: b8 0e 00 00 00 mov $0xe,%eax + eb8: cd 40 int $0x40 + eba: c3 ret + +00000ebb : +SYSCALL(open) + ebb: b8 0f 00 00 00 mov $0xf,%eax + ec0: cd 40 int $0x40 + ec2: c3 ret + +00000ec3 : +SYSCALL(write) + ec3: b8 10 00 00 00 mov $0x10,%eax + ec8: cd 40 int $0x40 + eca: c3 ret + +00000ecb : +SYSCALL(mknod) + ecb: b8 11 00 00 00 mov $0x11,%eax + ed0: cd 40 int $0x40 + ed2: c3 ret + +00000ed3 : +SYSCALL(unlink) + ed3: b8 12 00 00 00 mov $0x12,%eax + ed8: cd 40 int $0x40 + eda: c3 ret + +00000edb : +SYSCALL(link) + edb: b8 13 00 00 00 mov $0x13,%eax + ee0: cd 40 int $0x40 + ee2: c3 ret + +00000ee3 : +SYSCALL(mkdir) + ee3: b8 14 00 00 00 mov $0x14,%eax + ee8: cd 40 int $0x40 + eea: c3 ret + +00000eeb : +SYSCALL(close) + eeb: b8 15 00 00 00 mov $0x15,%eax + ef0: cd 40 int $0x40 + ef2: c3 ret + +00000ef3 : +SYSCALL(getch) + ef3: b8 16 00 00 00 mov $0x16,%eax + ef8: cd 40 int $0x40 + efa: c3 ret + +00000efb : +SYSCALL(greeting) + efb: b8 17 00 00 00 mov $0x17,%eax + f00: cd 40 int $0x40 + f02: c3 ret + +00000f03 : +SYSCALL(shutdown) + f03: b8 18 00 00 00 mov $0x18,%eax + f08: cd 40 int $0x40 + f0a: c3 ret + f0b: 66 90 xchg %ax,%ax + f0d: 66 90 xchg %ax,%ax + f0f: 90 nop + +00000f10 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + f10: 55 push %ebp + f11: 89 e5 mov %esp,%ebp + f13: 57 push %edi + f14: 56 push %esi + f15: 53 push %ebx + f16: 83 ec 3c sub $0x3c,%esp + f19: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + f1c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + f1e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + f21: 85 d2 test %edx,%edx + f23: 0f 89 7f 00 00 00 jns fa8 + f29: f6 45 08 01 testb $0x1,0x8(%ebp) + f2d: 74 79 je fa8 + neg = 1; + f2f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + f36: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + f38: 31 db xor %ebx,%ebx + f3a: 8d 75 d7 lea -0x29(%ebp),%esi + f3d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + f40: 89 c8 mov %ecx,%eax + f42: 31 d2 xor %edx,%edx + f44: 89 cf mov %ecx,%edi + f46: f7 75 c4 divl -0x3c(%ebp) + f49: 0f b6 92 30 14 00 00 movzbl 0x1430(%edx),%edx + f50: 89 45 c0 mov %eax,-0x40(%ebp) + f53: 89 d8 mov %ebx,%eax + f55: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + f58: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + f5b: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + f5e: 39 7d c4 cmp %edi,-0x3c(%ebp) + f61: 76 dd jbe f40 + if (neg) { + f63: 8b 4d bc mov -0x44(%ebp),%ecx + f66: 85 c9 test %ecx,%ecx + f68: 74 0c je f76 + buf[i++] = '-'; + f6a: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + f6f: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + f71: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + f76: 8b 7d b8 mov -0x48(%ebp),%edi + f79: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + f7d: eb 07 jmp f86 + f7f: 90 nop + putc(fd, buf[i]); + f80: 0f b6 13 movzbl (%ebx),%edx + f83: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + f86: 83 ec 04 sub $0x4,%esp + f89: 88 55 d7 mov %dl,-0x29(%ebp) + f8c: 6a 01 push $0x1 + f8e: 56 push %esi + f8f: 57 push %edi + f90: e8 2e ff ff ff call ec3 + while (--i >= 0) { + f95: 83 c4 10 add $0x10,%esp + f98: 39 de cmp %ebx,%esi + f9a: 75 e4 jne f80 + } +} + f9c: 8d 65 f4 lea -0xc(%ebp),%esp + f9f: 5b pop %ebx + fa0: 5e pop %esi + fa1: 5f pop %edi + fa2: 5d pop %ebp + fa3: c3 ret + fa4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + fa8: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + faf: eb 87 jmp f38 + fb1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + fb8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + fbf: 90 nop + +00000fc0 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + fc0: 55 push %ebp + fc1: 89 e5 mov %esp,%ebp + fc3: 57 push %edi + fc4: 56 push %esi + fc5: 53 push %ebx + fc6: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + fc9: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + fcc: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + fcf: 0f b6 13 movzbl (%ebx),%edx + fd2: 84 d2 test %dl,%dl + fd4: 74 6a je 1040 + ap = (uint*)(void*)&fmt + 1; + fd6: 8d 45 10 lea 0x10(%ebp),%eax + fd9: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + fdc: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + fdf: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + fe1: 89 45 d0 mov %eax,-0x30(%ebp) + fe4: eb 36 jmp 101c + fe6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + fed: 8d 76 00 lea 0x0(%esi),%esi + ff0: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + ff3: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + ff8: 83 f8 25 cmp $0x25,%eax + ffb: 74 15 je 1012 + write(fd, &c, 1); + ffd: 83 ec 04 sub $0x4,%esp + 1000: 88 55 e7 mov %dl,-0x19(%ebp) + 1003: 6a 01 push $0x1 + 1005: 57 push %edi + 1006: 56 push %esi + 1007: e8 b7 fe ff ff call ec3 + 100c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 100f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 1012: 0f b6 13 movzbl (%ebx),%edx + 1015: 83 c3 01 add $0x1,%ebx + 1018: 84 d2 test %dl,%dl + 101a: 74 24 je 1040 + c = fmt[i] & 0xff; + 101c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 101f: 85 c9 test %ecx,%ecx + 1021: 74 cd je ff0 + } + } + else if (state == '%') { + 1023: 83 f9 25 cmp $0x25,%ecx + 1026: 75 ea jne 1012 + if (c == 'd') { + 1028: 83 f8 25 cmp $0x25,%eax + 102b: 0f 84 07 01 00 00 je 1138 + 1031: 83 e8 63 sub $0x63,%eax + 1034: 83 f8 15 cmp $0x15,%eax + 1037: 77 17 ja 1050 + 1039: ff 24 85 d8 13 00 00 jmp *0x13d8(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 1040: 8d 65 f4 lea -0xc(%ebp),%esp + 1043: 5b pop %ebx + 1044: 5e pop %esi + 1045: 5f pop %edi + 1046: 5d pop %ebp + 1047: c3 ret + 1048: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 104f: 90 nop + write(fd, &c, 1); + 1050: 83 ec 04 sub $0x4,%esp + 1053: 88 55 d4 mov %dl,-0x2c(%ebp) + 1056: 6a 01 push $0x1 + 1058: 57 push %edi + 1059: 56 push %esi + 105a: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 105e: e8 60 fe ff ff call ec3 + putc(fd, c); + 1063: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 1067: 83 c4 0c add $0xc,%esp + 106a: 88 55 e7 mov %dl,-0x19(%ebp) + 106d: 6a 01 push $0x1 + 106f: 57 push %edi + 1070: 56 push %esi + 1071: e8 4d fe ff ff call ec3 + putc(fd, c); + 1076: 83 c4 10 add $0x10,%esp + state = 0; + 1079: 31 c9 xor %ecx,%ecx + 107b: eb 95 jmp 1012 + 107d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 1080: 83 ec 0c sub $0xc,%esp + 1083: b9 10 00 00 00 mov $0x10,%ecx + 1088: 6a 00 push $0x0 + 108a: 8b 45 d0 mov -0x30(%ebp),%eax + 108d: 8b 10 mov (%eax),%edx + 108f: 89 f0 mov %esi,%eax + 1091: e8 7a fe ff ff call f10 + ap++; + 1096: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 109a: 83 c4 10 add $0x10,%esp + state = 0; + 109d: 31 c9 xor %ecx,%ecx + 109f: e9 6e ff ff ff jmp 1012 + 10a4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 10a8: 8b 45 d0 mov -0x30(%ebp),%eax + 10ab: 8b 10 mov (%eax),%edx + ap++; + 10ad: 83 c0 04 add $0x4,%eax + 10b0: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 10b3: 85 d2 test %edx,%edx + 10b5: 0f 84 8d 00 00 00 je 1148 + while (*s != 0) { + 10bb: 0f b6 02 movzbl (%edx),%eax + state = 0; + 10be: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 10c0: 84 c0 test %al,%al + 10c2: 0f 84 4a ff ff ff je 1012 + 10c8: 89 5d d4 mov %ebx,-0x2c(%ebp) + 10cb: 89 d3 mov %edx,%ebx + 10cd: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 10d0: 83 ec 04 sub $0x4,%esp + s++; + 10d3: 83 c3 01 add $0x1,%ebx + 10d6: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 10d9: 6a 01 push $0x1 + 10db: 57 push %edi + 10dc: 56 push %esi + 10dd: e8 e1 fd ff ff call ec3 + while (*s != 0) { + 10e2: 0f b6 03 movzbl (%ebx),%eax + 10e5: 83 c4 10 add $0x10,%esp + 10e8: 84 c0 test %al,%al + 10ea: 75 e4 jne 10d0 + state = 0; + 10ec: 8b 5d d4 mov -0x2c(%ebp),%ebx + 10ef: 31 c9 xor %ecx,%ecx + 10f1: e9 1c ff ff ff jmp 1012 + 10f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 10fd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 1100: 83 ec 0c sub $0xc,%esp + 1103: b9 0a 00 00 00 mov $0xa,%ecx + 1108: 6a 01 push $0x1 + 110a: e9 7b ff ff ff jmp 108a + 110f: 90 nop + putc(fd, *ap); + 1110: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 1113: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 1116: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 1118: 6a 01 push $0x1 + 111a: 57 push %edi + 111b: 56 push %esi + putc(fd, *ap); + 111c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 111f: e8 9f fd ff ff call ec3 + ap++; + 1124: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 1128: 83 c4 10 add $0x10,%esp + state = 0; + 112b: 31 c9 xor %ecx,%ecx + 112d: e9 e0 fe ff ff jmp 1012 + 1132: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 1138: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 113b: 83 ec 04 sub $0x4,%esp + 113e: e9 2a ff ff ff jmp 106d + 1143: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1147: 90 nop + s = "(null)"; + 1148: ba d0 13 00 00 mov $0x13d0,%edx + while (*s != 0) { + 114d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 1150: b8 28 00 00 00 mov $0x28,%eax + 1155: 89 d3 mov %edx,%ebx + 1157: e9 74 ff ff ff jmp 10d0 + 115c: 66 90 xchg %ax,%ax + 115e: 66 90 xchg %ax,%ax + +00001160 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 1160: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 1161: a1 84 1a 00 00 mov 0x1a84,%eax +void free(void *ap) { + 1166: 89 e5 mov %esp,%ebp + 1168: 57 push %edi + 1169: 56 push %esi + 116a: 53 push %ebx + 116b: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 116e: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 1171: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1178: 89 c2 mov %eax,%edx + 117a: 8b 00 mov (%eax),%eax + 117c: 39 ca cmp %ecx,%edx + 117e: 73 30 jae 11b0 + 1180: 39 c1 cmp %eax,%ecx + 1182: 72 04 jb 1188 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 1184: 39 c2 cmp %eax,%edx + 1186: 72 f0 jb 1178 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 1188: 8b 73 fc mov -0x4(%ebx),%esi + 118b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 118e: 39 f8 cmp %edi,%eax + 1190: 74 30 je 11c2 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 1192: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 1195: 8b 42 04 mov 0x4(%edx),%eax + 1198: 8d 34 c2 lea (%edx,%eax,8),%esi + 119b: 39 f1 cmp %esi,%ecx + 119d: 74 3a je 11d9 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 119f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 11a1: 5b pop %ebx + freep = p; + 11a2: 89 15 84 1a 00 00 mov %edx,0x1a84 +} + 11a8: 5e pop %esi + 11a9: 5f pop %edi + 11aa: 5d pop %ebp + 11ab: c3 ret + 11ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 11b0: 39 c2 cmp %eax,%edx + 11b2: 72 c4 jb 1178 + 11b4: 39 c1 cmp %eax,%ecx + 11b6: 73 c0 jae 1178 + if (bp + bp->s.size == p->s.ptr) { + 11b8: 8b 73 fc mov -0x4(%ebx),%esi + 11bb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 11be: 39 f8 cmp %edi,%eax + 11c0: 75 d0 jne 1192 + bp->s.size += p->s.ptr->s.size; + 11c2: 03 70 04 add 0x4(%eax),%esi + 11c5: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 11c8: 8b 02 mov (%edx),%eax + 11ca: 8b 00 mov (%eax),%eax + 11cc: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 11cf: 8b 42 04 mov 0x4(%edx),%eax + 11d2: 8d 34 c2 lea (%edx,%eax,8),%esi + 11d5: 39 f1 cmp %esi,%ecx + 11d7: 75 c6 jne 119f + p->s.size += bp->s.size; + 11d9: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 11dc: 89 15 84 1a 00 00 mov %edx,0x1a84 + p->s.size += bp->s.size; + 11e2: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 11e5: 8b 4b f8 mov -0x8(%ebx),%ecx + 11e8: 89 0a mov %ecx,(%edx) +} + 11ea: 5b pop %ebx + 11eb: 5e pop %esi + 11ec: 5f pop %edi + 11ed: 5d pop %ebp + 11ee: c3 ret + 11ef: 90 nop + +000011f0 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 11f0: 55 push %ebp + 11f1: 89 e5 mov %esp,%ebp + 11f3: 57 push %edi + 11f4: 56 push %esi + 11f5: 53 push %ebx + 11f6: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 11f9: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 11fc: 8b 3d 84 1a 00 00 mov 0x1a84,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 1202: 8d 70 07 lea 0x7(%eax),%esi + 1205: c1 ee 03 shr $0x3,%esi + 1208: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 120b: 85 ff test %edi,%edi + 120d: 0f 84 9d 00 00 00 je 12b0 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 1213: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 1215: 8b 4a 04 mov 0x4(%edx),%ecx + 1218: 39 f1 cmp %esi,%ecx + 121a: 73 6a jae 1286 + 121c: bb 00 10 00 00 mov $0x1000,%ebx + 1221: 39 de cmp %ebx,%esi + 1223: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 1226: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 122d: 89 45 e4 mov %eax,-0x1c(%ebp) + 1230: eb 17 jmp 1249 + 1232: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 1238: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 123a: 8b 48 04 mov 0x4(%eax),%ecx + 123d: 39 f1 cmp %esi,%ecx + 123f: 73 4f jae 1290 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 1241: 8b 3d 84 1a 00 00 mov 0x1a84,%edi + 1247: 89 c2 mov %eax,%edx + 1249: 39 d7 cmp %edx,%edi + 124b: 75 eb jne 1238 + p = sbrk(nu * sizeof(Header)); + 124d: 83 ec 0c sub $0xc,%esp + 1250: ff 75 e4 push -0x1c(%ebp) + 1253: e8 4b fc ff ff call ea3 + if (p == (char*)-1) { + 1258: 83 c4 10 add $0x10,%esp + 125b: 83 f8 ff cmp $0xffffffff,%eax + 125e: 74 1c je 127c + hp->s.size = nu; + 1260: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 1263: 83 ec 0c sub $0xc,%esp + 1266: 83 c0 08 add $0x8,%eax + 1269: 50 push %eax + 126a: e8 f1 fe ff ff call 1160 + return freep; + 126f: 8b 15 84 1a 00 00 mov 0x1a84,%edx + if ((p = morecore(nunits)) == 0) { + 1275: 83 c4 10 add $0x10,%esp + 1278: 85 d2 test %edx,%edx + 127a: 75 bc jne 1238 + return 0; + } + } + } +} + 127c: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 127f: 31 c0 xor %eax,%eax +} + 1281: 5b pop %ebx + 1282: 5e pop %esi + 1283: 5f pop %edi + 1284: 5d pop %ebp + 1285: c3 ret + if (p->s.size >= nunits) { + 1286: 89 d0 mov %edx,%eax + 1288: 89 fa mov %edi,%edx + 128a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 1290: 39 ce cmp %ecx,%esi + 1292: 74 4c je 12e0 + p->s.size -= nunits; + 1294: 29 f1 sub %esi,%ecx + 1296: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 1299: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 129c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 129f: 89 15 84 1a 00 00 mov %edx,0x1a84 +} + 12a5: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 12a8: 83 c0 08 add $0x8,%eax +} + 12ab: 5b pop %ebx + 12ac: 5e pop %esi + 12ad: 5f pop %edi + 12ae: 5d pop %ebp + 12af: c3 ret + base.s.ptr = freep = prevp = &base; + 12b0: c7 05 84 1a 00 00 88 movl $0x1a88,0x1a84 + 12b7: 1a 00 00 + base.s.size = 0; + 12ba: bf 88 1a 00 00 mov $0x1a88,%edi + base.s.ptr = freep = prevp = &base; + 12bf: c7 05 88 1a 00 00 88 movl $0x1a88,0x1a88 + 12c6: 1a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 12c9: 89 fa mov %edi,%edx + base.s.size = 0; + 12cb: c7 05 8c 1a 00 00 00 movl $0x0,0x1a8c + 12d2: 00 00 00 + if (p->s.size >= nunits) { + 12d5: e9 42 ff ff ff jmp 121c + 12da: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 12e0: 8b 08 mov (%eax),%ecx + 12e2: 89 0a mov %ecx,(%edx) + 12e4: eb b9 jmp 129f diff --git a/sh.c b/sh.c new file mode 100644 index 0000000..1e76d7b --- /dev/null +++ b/sh.c @@ -0,0 +1,482 @@ +// Shell. + +#include "types.h" +#include "user.h" +#include "fcntl.h" + +// Parsed command representation +#define EXEC 1 +#define REDIR 2 +#define PIPE 3 +#define LIST 4 +#define BACK 5 + +#define MAXARGS 10 + +struct cmd { + int type; +}; + +struct execcmd { + int type; + char *argv[MAXARGS]; + char *eargv[MAXARGS]; +}; + +struct redircmd { + int type; + struct cmd *cmd; + char *file; + char *efile; + int mode; + int fd; +}; + +struct pipecmd { + int type; + struct cmd *left; + struct cmd *right; +}; + +struct listcmd { + int type; + struct cmd *left; + struct cmd *right; +}; + +struct backcmd { + int type; + struct cmd *cmd; +}; + +int fork1(void); // Fork but panics on failure. +void panic(char*); +struct cmd *parsecmd(char*); + +// Execute cmd. Never returns. +void runcmd(struct cmd *cmd) { + int p[2]; + struct backcmd *bcmd; + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if (cmd == 0) { + exit(); + } + + switch (cmd->type) { + default: + panic("runcmd"); + + case EXEC: + ecmd = (struct execcmd*)cmd; + if (ecmd->argv[0] == 0) { + exit(); + } + exec(ecmd->argv[0], ecmd->argv); + printf(2, "exec %s failed\n", ecmd->argv[0]); + break; + + case REDIR: + rcmd = (struct redircmd*)cmd; + close(rcmd->fd); + if (open(rcmd->file, rcmd->mode) < 0) { + printf(2, "open %s failed\n", rcmd->file); + exit(); + } + runcmd(rcmd->cmd); + break; + + case LIST: + lcmd = (struct listcmd*)cmd; + if (fork1() == 0) { + runcmd(lcmd->left); + } + wait(); + runcmd(lcmd->right); + break; + + case PIPE: + pcmd = (struct pipecmd*)cmd; + if (pipe(p) < 0) { + panic("pipe"); + } + if (fork1() == 0) { + close(1); + dup(p[1]); + close(p[0]); + close(p[1]); + runcmd(pcmd->left); + } + if (fork1() == 0) { + close(0); + dup(p[0]); + close(p[0]); + close(p[1]); + runcmd(pcmd->right); + } + close(p[0]); + close(p[1]); + wait(); + wait(); + break; + + case BACK: + bcmd = (struct backcmd*)cmd; + if (fork1() == 0) { + runcmd(bcmd->cmd); + } + break; + } + exit(); +} + +int getcmd(char *buf, int nbuf) { + printf(2, "$ "); + memset(buf, 0, nbuf); + gets(buf, nbuf); + if (buf[0] == 0) { // EOF + return -1; + } + return 0; +} + +int main(void) { + static char buf[100]; + int fd; + + // Ensure that three file descriptors are open. + while ((fd = open("console", O_RDWR)) >= 0) { + if (fd >= 3) { + close(fd); + break; + } + } + + // Read and run input commands. + while (getcmd(buf, sizeof(buf)) >= 0) { + if (buf[0] == 'e' && buf[1] == 'x' && buf[2] == 'i' && buf[3] == 't') { + exit(); + } + if (buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' ') { + // Chdir must be called by the parent, not the child. + buf[strlen(buf) - 1] = 0; // chop \n + if (chdir(buf + 3) < 0) { + printf(2, "cannot cd %s\n", buf + 3); + } + continue; + } + if (fork1() == 0) { + runcmd(parsecmd(buf)); + } + wait(); + } + exit(); +} + +void panic(char *s) { + printf(2, "%s\n", s); + exit(); +} + +int fork1(void) { + int pid; + + pid = fork(); + if (pid == -1) { + panic("fork"); + } + return pid; +} + + +// Constructors + +struct cmd* execcmd(void) { + struct execcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = EXEC; + return (struct cmd*)cmd; +} + +struct cmd* redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd) { + struct redircmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = REDIR; + cmd->cmd = subcmd; + cmd->file = file; + cmd->efile = efile; + cmd->mode = mode; + cmd->fd = fd; + return (struct cmd*)cmd; +} + +struct cmd* pipecmd(struct cmd *left, struct cmd *right) { + struct pipecmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = PIPE; + cmd->left = left; + cmd->right = right; + return (struct cmd*)cmd; +} + +struct cmd* listcmd(struct cmd *left, struct cmd *right) { + struct listcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = LIST; + cmd->left = left; + cmd->right = right; + return (struct cmd*)cmd; +} + +struct cmd* backcmd(struct cmd *subcmd) { + struct backcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = BACK; + cmd->cmd = subcmd; + return (struct cmd*)cmd; +} + +// Parsing + +char whitespace[] = " \t\r\n\v"; +char symbols[] = "<|>&;()"; + +int gettoken(char **ps, char *es, char **q, char **eq) { + char *s; + int ret; + + s = *ps; + while (s < es && strchr(whitespace, *s)) { + s++; + } + if (q) { + *q = s; + } + ret = *s; + switch (*s) { + case 0: + break; + case '|': + case '(': + case ')': + case ';': + case '&': + case '<': + s++; + break; + case '>': + s++; + if (*s == '>') { + ret = '+'; + s++; + } + break; + default: + ret = 'a'; + while (s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) { + s++; + } + break; + } + if (eq) { + *eq = s; + } + + while (s < es && strchr(whitespace, *s)) { + s++; + } + *ps = s; + return ret; +} + +int peek(char **ps, char *es, char *toks) { + char *s; + + s = *ps; + while (s < es && strchr(whitespace, *s)) { + s++; + } + *ps = s; + return *s && strchr(toks, *s); +} + +struct cmd *parseline(char**, char*); +struct cmd *parsepipe(char**, char*); +struct cmd *parseexec(char**, char*); +struct cmd *nulterminate(struct cmd*); + +struct cmd* parsecmd(char *s) { + char *es; + struct cmd *cmd; + + es = s + strlen(s); + cmd = parseline(&s, es); + peek(&s, es, ""); + if (s != es) { + printf(2, "leftovers: %s\n", s); + panic("syntax"); + } + nulterminate(cmd); + return cmd; +} + +struct cmd* parseline(char **ps, char *es) { + struct cmd *cmd; + + cmd = parsepipe(ps, es); + while (peek(ps, es, "&")) { + gettoken(ps, es, 0, 0); + cmd = backcmd(cmd); + } + if (peek(ps, es, ";")) { + gettoken(ps, es, 0, 0); + cmd = listcmd(cmd, parseline(ps, es)); + } + return cmd; +} + +struct cmd* parsepipe(char **ps, char *es) { + struct cmd *cmd; + + cmd = parseexec(ps, es); + if (peek(ps, es, "|")) { + gettoken(ps, es, 0, 0); + cmd = pipecmd(cmd, parsepipe(ps, es)); + } + return cmd; +} + +struct cmd* parseredirs(struct cmd *cmd, char **ps, char *es) { + int tok; + char *q, *eq; + + while (peek(ps, es, "<>")) { + tok = gettoken(ps, es, 0, 0); + if (gettoken(ps, es, &q, &eq) != 'a') { + panic("missing file for redirection"); + } + switch (tok) { + case '<': + cmd = redircmd(cmd, q, eq, O_RDONLY, 0); + break; + case '>': + cmd = redircmd(cmd, q, eq, O_WRONLY | O_CREATE, 1); + break; + case '+': // >> + cmd = redircmd(cmd, q, eq, O_WRONLY | O_CREATE, 1); + break; + } + } + return cmd; +} + +struct cmd* parseblock(char **ps, char *es) { + struct cmd *cmd; + + if (!peek(ps, es, "(")) { + panic("parseblock"); + } + gettoken(ps, es, 0, 0); + cmd = parseline(ps, es); + if (!peek(ps, es, ")")) { + panic("syntax - missing )"); + } + gettoken(ps, es, 0, 0); + cmd = parseredirs(cmd, ps, es); + return cmd; +} + +struct cmd* parseexec(char **ps, char *es) { + char *q, *eq; + int tok, argc; + struct execcmd *cmd; + struct cmd *ret; + + if (peek(ps, es, "(")) { + return parseblock(ps, es); + } + + ret = execcmd(); + cmd = (struct execcmd*)ret; + + argc = 0; + ret = parseredirs(ret, ps, es); + while (!peek(ps, es, "|)&;")) { + if ((tok = gettoken(ps, es, &q, &eq)) == 0) { + break; + } + if (tok != 'a') { + panic("syntax"); + } + cmd->argv[argc] = q; + cmd->eargv[argc] = eq; + argc++; + if (argc >= MAXARGS) { + panic("too many args"); + } + ret = parseredirs(ret, ps, es); + } + cmd->argv[argc] = 0; + cmd->eargv[argc] = 0; + return ret; +} + +// NUL-terminate all the counted strings. +struct cmd* nulterminate(struct cmd *cmd) { + int i; + struct backcmd *bcmd; + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if (cmd == 0) { + return 0; + } + + switch (cmd->type) { + case EXEC: + ecmd = (struct execcmd*)cmd; + for (i = 0; ecmd->argv[i]; i++) { + *ecmd->eargv[i] = 0; + } + break; + + case REDIR: + rcmd = (struct redircmd*)cmd; + nulterminate(rcmd->cmd); + *rcmd->efile = 0; + break; + + case PIPE: + pcmd = (struct pipecmd*)cmd; + nulterminate(pcmd->left); + nulterminate(pcmd->right); + break; + + case LIST: + lcmd = (struct listcmd*)cmd; + nulterminate(lcmd->left); + nulterminate(lcmd->right); + break; + + case BACK: + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + break; + } + return cmd; +} diff --git a/sh.d b/sh.d new file mode 100644 index 0000000..51ddf2d --- /dev/null +++ b/sh.d @@ -0,0 +1 @@ +sh.o: sh.c /usr/include/stdc-predef.h types.h user.h fcntl.h diff --git a/sh.o b/sh.o new file mode 100644 index 0000000..1a9669f Binary files /dev/null and b/sh.o differ diff --git a/sh.sym b/sh.sym new file mode 100644 index 0000000..fb947b6 --- /dev/null +++ b/sh.sym @@ -0,0 +1,69 @@ +00000000 sh.c +00001a20 buf.0 +00000000 ulib.c +00000000 printf.c +00000f10 printint +00001430 digits.0 +00000000 umalloc.c +00001a84 freep +00001a88 base +00000c00 strcpy +00000fc0 printf +00000efb greeting +00000e20 memmove +00000ecb mknod +00000370 execcmd +00000d20 gets +00000e9b getpid +000008e0 parsepipe +00000b90 parsecmd +00000470 backcmd +00000600 peek +00000680 parseredirs +000004a0 gettoken +000011f0 malloc +00000eab sleep +00001a0c whitespace +000001c0 fork1 +00000ae0 nulterminate +00000e63 pipe +00000ef3 getch +00000160 getcmd +00000ec3 write +00000e83 fstat +00000e73 kill +00000e8b chdir +00000970 parseline +000001e0 runcmd +00000a50 parseblock +00000e7b exec +00000e5b wait +00001a04 symbols +00000e6b read +000007c0 parseexec +00000ed3 unlink +000001a0 panic +00000e4b fork +00000ea3 sbrk +00000eb3 uptime +00001a12 __bss_start +00000cc0 memset +00000000 main +00000c30 strcmp +00000f03 shutdown +00000e93 dup +000003f0 pipecmd +000003a0 redircmd +00000d90 stat +00001a12 _edata +00001a90 _end +00000edb link +00000e53 exit +00000de0 atoi +00000c90 strlen +00000ebb open +00000ce0 strchr +00000ee3 mkdir +00000eeb close +00000430 listcmd +00001160 free diff --git a/shutdown.asm b/shutdown.asm new file mode 100644 index 0000000..29fb272 --- /dev/null +++ b/shutdown.asm @@ -0,0 +1,1198 @@ + +_shutdown: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: 53 push %ebx + 10: 51 push %ecx + 11: 83 ec 18 sub $0x18,%esp + 14: 8b 01 mov (%ecx),%eax + 16: 8b 71 04 mov 0x4(%ecx),%esi + 19: 89 45 e4 mov %eax,-0x1c(%ebp) + int restart = 0; + + for (int i = 1; i < argc; i++) { + 1c: 83 f8 01 cmp $0x1,%eax + 1f: 7e 58 jle 79 + 21: bb 01 00 00 00 mov $0x1,%ebx + int restart = 0; + 26: 31 ff xor %edi,%edi + 28: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2f: 90 nop + if (strcmp(argv[i], "-r") == 0) { + 30: 83 ec 08 sub $0x8,%esp + 33: 68 78 07 00 00 push $0x778 + 38: ff 34 9e push (%esi,%ebx,4) + 3b: e8 80 00 00 00 call c0 + 40: 83 c4 10 add $0x10,%esp + restart = 1; + 43: 85 c0 test %eax,%eax + 45: b8 01 00 00 00 mov $0x1,%eax + 4a: 0f 44 f8 cmove %eax,%edi + for (int i = 1; i < argc; i++) { + 4d: 83 c3 01 add $0x1,%ebx + 50: 39 5d e4 cmp %ebx,-0x1c(%ebp) + 53: 75 db jne 30 + } + } + + switch(restart) { + 55: 83 ff 01 cmp $0x1,%edi + 58: 75 1f jne 79 + case 0: + printf(1, "Shutting Down...\n"); + break; + case 1: + printf(1, "Restarting...\n"); + 5a: 50 push %eax + 5b: 50 push %eax + 5c: 68 8d 07 00 00 push $0x78d + 61: 6a 01 push $0x1 + 63: e8 e8 03 00 00 call 450 + break; + 68: 83 c4 10 add $0x10,%esp + } + + shutdown(restart); + 6b: 83 ec 0c sub $0xc,%esp + 6e: 57 push %edi + 6f: e8 1f 03 00 00 call 393 + exit(); + 74: e8 6a 02 00 00 call 2e3 + printf(1, "Shutting Down...\n"); + 79: 52 push %edx + break; + 7a: 31 ff xor %edi,%edi + printf(1, "Shutting Down...\n"); + 7c: 52 push %edx + 7d: 68 7b 07 00 00 push $0x77b + 82: 6a 01 push $0x1 + 84: e8 c7 03 00 00 call 450 + break; + 89: 83 c4 10 add $0x10,%esp + 8c: eb dd jmp 6b + 8e: 66 90 xchg %ax,%ax + +00000090 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 90: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 91: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 93: 89 e5 mov %esp,%ebp + 95: 53 push %ebx + 96: 8b 4d 08 mov 0x8(%ebp),%ecx + 99: 8b 5d 0c mov 0xc(%ebp),%ebx + 9c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + a0: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + a4: 88 14 01 mov %dl,(%ecx,%eax,1) + a7: 83 c0 01 add $0x1,%eax + aa: 84 d2 test %dl,%dl + ac: 75 f2 jne a0 + ; + } + return os; +} + ae: 8b 5d fc mov -0x4(%ebp),%ebx + b1: 89 c8 mov %ecx,%eax + b3: c9 leave + b4: c3 ret + b5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + bc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000000c0 : + +int strcmp(const char *p, const char *q) { + c0: 55 push %ebp + c1: 89 e5 mov %esp,%ebp + c3: 53 push %ebx + c4: 8b 55 08 mov 0x8(%ebp),%edx + c7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + ca: 0f b6 02 movzbl (%edx),%eax + cd: 84 c0 test %al,%al + cf: 75 17 jne e8 + d1: eb 3a jmp 10d + d3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + d7: 90 nop + d8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + dc: 83 c2 01 add $0x1,%edx + df: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + e2: 84 c0 test %al,%al + e4: 74 1a je 100 + p++, q++; + e6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + e8: 0f b6 19 movzbl (%ecx),%ebx + eb: 38 c3 cmp %al,%bl + ed: 74 e9 je d8 + } + return (uchar) * p - (uchar) * q; + ef: 29 d8 sub %ebx,%eax +} + f1: 8b 5d fc mov -0x4(%ebp),%ebx + f4: c9 leave + f5: c3 ret + f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + fd: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 100: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 104: 31 c0 xor %eax,%eax + 106: 29 d8 sub %ebx,%eax +} + 108: 8b 5d fc mov -0x4(%ebp),%ebx + 10b: c9 leave + 10c: c3 ret + return (uchar) * p - (uchar) * q; + 10d: 0f b6 19 movzbl (%ecx),%ebx + 110: 31 c0 xor %eax,%eax + 112: eb db jmp ef + 114: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 11b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 11f: 90 nop + +00000120 : + +uint strlen(const char *s) { + 120: 55 push %ebp + 121: 89 e5 mov %esp,%ebp + 123: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 126: 80 3a 00 cmpb $0x0,(%edx) + 129: 74 15 je 140 + 12b: 31 c0 xor %eax,%eax + 12d: 8d 76 00 lea 0x0(%esi),%esi + 130: 83 c0 01 add $0x1,%eax + 133: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 137: 89 c1 mov %eax,%ecx + 139: 75 f5 jne 130 + ; + } + return n; +} + 13b: 89 c8 mov %ecx,%eax + 13d: 5d pop %ebp + 13e: c3 ret + 13f: 90 nop + for (n = 0; s[n]; n++) { + 140: 31 c9 xor %ecx,%ecx +} + 142: 5d pop %ebp + 143: 89 c8 mov %ecx,%eax + 145: c3 ret + 146: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 14d: 8d 76 00 lea 0x0(%esi),%esi + +00000150 : + +void* memset(void *dst, int c, uint n) { + 150: 55 push %ebp + 151: 89 e5 mov %esp,%ebp + 153: 57 push %edi + 154: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 157: 8b 4d 10 mov 0x10(%ebp),%ecx + 15a: 8b 45 0c mov 0xc(%ebp),%eax + 15d: 89 d7 mov %edx,%edi + 15f: fc cld + 160: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 162: 8b 7d fc mov -0x4(%ebp),%edi + 165: 89 d0 mov %edx,%eax + 167: c9 leave + 168: c3 ret + 169: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000170 : + +char* strchr(const char *s, char c) { + 170: 55 push %ebp + 171: 89 e5 mov %esp,%ebp + 173: 8b 45 08 mov 0x8(%ebp),%eax + 176: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 17a: 0f b6 10 movzbl (%eax),%edx + 17d: 84 d2 test %dl,%dl + 17f: 75 12 jne 193 + 181: eb 1d jmp 1a0 + 183: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 187: 90 nop + 188: 0f b6 50 01 movzbl 0x1(%eax),%edx + 18c: 83 c0 01 add $0x1,%eax + 18f: 84 d2 test %dl,%dl + 191: 74 0d je 1a0 + if (*s == c) { + 193: 38 d1 cmp %dl,%cl + 195: 75 f1 jne 188 + return (char*)s; + } + } + return 0; +} + 197: 5d pop %ebp + 198: c3 ret + 199: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 1a0: 31 c0 xor %eax,%eax +} + 1a2: 5d pop %ebp + 1a3: c3 ret + 1a4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ab: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1af: 90 nop + +000001b0 : + +char* gets(char *buf, int max) { + 1b0: 55 push %ebp + 1b1: 89 e5 mov %esp,%ebp + 1b3: 57 push %edi + 1b4: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 1b5: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 1b8: 53 push %ebx + for (i = 0; i + 1 < max;) { + 1b9: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 1bb: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 1be: eb 27 jmp 1e7 + cc = read(0, &c, 1); + 1c0: 83 ec 04 sub $0x4,%esp + 1c3: 6a 01 push $0x1 + 1c5: 57 push %edi + 1c6: 6a 00 push $0x0 + 1c8: e8 2e 01 00 00 call 2fb + if (cc < 1) { + 1cd: 83 c4 10 add $0x10,%esp + 1d0: 85 c0 test %eax,%eax + 1d2: 7e 1d jle 1f1 + break; + } + buf[i++] = c; + 1d4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 1d8: 8b 55 08 mov 0x8(%ebp),%edx + 1db: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 1df: 3c 0a cmp $0xa,%al + 1e1: 74 1d je 200 + 1e3: 3c 0d cmp $0xd,%al + 1e5: 74 19 je 200 + for (i = 0; i + 1 < max;) { + 1e7: 89 de mov %ebx,%esi + 1e9: 83 c3 01 add $0x1,%ebx + 1ec: 3b 5d 0c cmp 0xc(%ebp),%ebx + 1ef: 7c cf jl 1c0 + break; + } + } + buf[i] = '\0'; + 1f1: 8b 45 08 mov 0x8(%ebp),%eax + 1f4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 1f8: 8d 65 f4 lea -0xc(%ebp),%esp + 1fb: 5b pop %ebx + 1fc: 5e pop %esi + 1fd: 5f pop %edi + 1fe: 5d pop %ebp + 1ff: c3 ret + buf[i] = '\0'; + 200: 8b 45 08 mov 0x8(%ebp),%eax + 203: 89 de mov %ebx,%esi + 205: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 209: 8d 65 f4 lea -0xc(%ebp),%esp + 20c: 5b pop %ebx + 20d: 5e pop %esi + 20e: 5f pop %edi + 20f: 5d pop %ebp + 210: c3 ret + 211: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 218: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 21f: 90 nop + +00000220 : + +int stat(const char *n, struct stat *st) { + 220: 55 push %ebp + 221: 89 e5 mov %esp,%ebp + 223: 56 push %esi + 224: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 225: 83 ec 08 sub $0x8,%esp + 228: 6a 00 push $0x0 + 22a: ff 75 08 push 0x8(%ebp) + 22d: e8 19 01 00 00 call 34b + if (fd < 0) { + 232: 83 c4 10 add $0x10,%esp + 235: 85 c0 test %eax,%eax + 237: 78 27 js 260 + return -1; + } + r = fstat(fd, st); + 239: 83 ec 08 sub $0x8,%esp + 23c: ff 75 0c push 0xc(%ebp) + 23f: 89 c3 mov %eax,%ebx + 241: 50 push %eax + 242: e8 cc 00 00 00 call 313 + close(fd); + 247: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 24a: 89 c6 mov %eax,%esi + close(fd); + 24c: e8 2a 01 00 00 call 37b + return r; + 251: 83 c4 10 add $0x10,%esp +} + 254: 8d 65 f8 lea -0x8(%ebp),%esp + 257: 89 f0 mov %esi,%eax + 259: 5b pop %ebx + 25a: 5e pop %esi + 25b: 5d pop %ebp + 25c: c3 ret + 25d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 260: be ff ff ff ff mov $0xffffffff,%esi + 265: eb ed jmp 254 + 267: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 26e: 66 90 xchg %ax,%ax + +00000270 : + +int atoi(const char *s) { + 270: 55 push %ebp + 271: 89 e5 mov %esp,%ebp + 273: 53 push %ebx + 274: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 277: 0f be 02 movsbl (%edx),%eax + 27a: 8d 48 d0 lea -0x30(%eax),%ecx + 27d: 80 f9 09 cmp $0x9,%cl + n = 0; + 280: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 285: 77 1e ja 2a5 + 287: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 28e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 290: 83 c2 01 add $0x1,%edx + 293: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 296: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 29a: 0f be 02 movsbl (%edx),%eax + 29d: 8d 58 d0 lea -0x30(%eax),%ebx + 2a0: 80 fb 09 cmp $0x9,%bl + 2a3: 76 eb jbe 290 + } + return n; +} + 2a5: 8b 5d fc mov -0x4(%ebp),%ebx + 2a8: 89 c8 mov %ecx,%eax + 2aa: c9 leave + 2ab: c3 ret + 2ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000002b0 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 2b0: 55 push %ebp + 2b1: 89 e5 mov %esp,%ebp + 2b3: 57 push %edi + 2b4: 8b 45 10 mov 0x10(%ebp),%eax + 2b7: 8b 55 08 mov 0x8(%ebp),%edx + 2ba: 56 push %esi + 2bb: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 2be: 85 c0 test %eax,%eax + 2c0: 7e 13 jle 2d5 + 2c2: 01 d0 add %edx,%eax + dst = vdst; + 2c4: 89 d7 mov %edx,%edi + 2c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2cd: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 2d0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 2d1: 39 f8 cmp %edi,%eax + 2d3: 75 fb jne 2d0 + } + return vdst; +} + 2d5: 5e pop %esi + 2d6: 89 d0 mov %edx,%eax + 2d8: 5f pop %edi + 2d9: 5d pop %ebp + 2da: c3 ret + +000002db : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 2db: b8 01 00 00 00 mov $0x1,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(exit) + 2e3: b8 02 00 00 00 mov $0x2,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(wait) + 2eb: b8 03 00 00 00 mov $0x3,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(pipe) + 2f3: b8 04 00 00 00 mov $0x4,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(read) + 2fb: b8 05 00 00 00 mov $0x5,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(kill) + 303: b8 06 00 00 00 mov $0x6,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(exec) + 30b: b8 07 00 00 00 mov $0x7,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(fstat) + 313: b8 08 00 00 00 mov $0x8,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(chdir) + 31b: b8 09 00 00 00 mov $0x9,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(dup) + 323: b8 0a 00 00 00 mov $0xa,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(getpid) + 32b: b8 0b 00 00 00 mov $0xb,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(sbrk) + 333: b8 0c 00 00 00 mov $0xc,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + +0000033b : +SYSCALL(sleep) + 33b: b8 0d 00 00 00 mov $0xd,%eax + 340: cd 40 int $0x40 + 342: c3 ret + +00000343 : +SYSCALL(uptime) + 343: b8 0e 00 00 00 mov $0xe,%eax + 348: cd 40 int $0x40 + 34a: c3 ret + +0000034b : +SYSCALL(open) + 34b: b8 0f 00 00 00 mov $0xf,%eax + 350: cd 40 int $0x40 + 352: c3 ret + +00000353 : +SYSCALL(write) + 353: b8 10 00 00 00 mov $0x10,%eax + 358: cd 40 int $0x40 + 35a: c3 ret + +0000035b : +SYSCALL(mknod) + 35b: b8 11 00 00 00 mov $0x11,%eax + 360: cd 40 int $0x40 + 362: c3 ret + +00000363 : +SYSCALL(unlink) + 363: b8 12 00 00 00 mov $0x12,%eax + 368: cd 40 int $0x40 + 36a: c3 ret + +0000036b : +SYSCALL(link) + 36b: b8 13 00 00 00 mov $0x13,%eax + 370: cd 40 int $0x40 + 372: c3 ret + +00000373 : +SYSCALL(mkdir) + 373: b8 14 00 00 00 mov $0x14,%eax + 378: cd 40 int $0x40 + 37a: c3 ret + +0000037b : +SYSCALL(close) + 37b: b8 15 00 00 00 mov $0x15,%eax + 380: cd 40 int $0x40 + 382: c3 ret + +00000383 : +SYSCALL(getch) + 383: b8 16 00 00 00 mov $0x16,%eax + 388: cd 40 int $0x40 + 38a: c3 ret + +0000038b : +SYSCALL(greeting) + 38b: b8 17 00 00 00 mov $0x17,%eax + 390: cd 40 int $0x40 + 392: c3 ret + +00000393 : +SYSCALL(shutdown) + 393: b8 18 00 00 00 mov $0x18,%eax + 398: cd 40 int $0x40 + 39a: c3 ret + 39b: 66 90 xchg %ax,%ax + 39d: 66 90 xchg %ax,%ax + 39f: 90 nop + +000003a0 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 3a0: 55 push %ebp + 3a1: 89 e5 mov %esp,%ebp + 3a3: 57 push %edi + 3a4: 56 push %esi + 3a5: 53 push %ebx + 3a6: 83 ec 3c sub $0x3c,%esp + 3a9: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 3ac: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 3ae: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 3b1: 85 d2 test %edx,%edx + 3b3: 0f 89 7f 00 00 00 jns 438 + 3b9: f6 45 08 01 testb $0x1,0x8(%ebp) + 3bd: 74 79 je 438 + neg = 1; + 3bf: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 3c6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 3c8: 31 db xor %ebx,%ebx + 3ca: 8d 75 d7 lea -0x29(%ebp),%esi + 3cd: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 3d0: 89 c8 mov %ecx,%eax + 3d2: 31 d2 xor %edx,%edx + 3d4: 89 cf mov %ecx,%edi + 3d6: f7 75 c4 divl -0x3c(%ebp) + 3d9: 0f b6 92 fc 07 00 00 movzbl 0x7fc(%edx),%edx + 3e0: 89 45 c0 mov %eax,-0x40(%ebp) + 3e3: 89 d8 mov %ebx,%eax + 3e5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 3e8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 3eb: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 3ee: 39 7d c4 cmp %edi,-0x3c(%ebp) + 3f1: 76 dd jbe 3d0 + if (neg) { + 3f3: 8b 4d bc mov -0x44(%ebp),%ecx + 3f6: 85 c9 test %ecx,%ecx + 3f8: 74 0c je 406 + buf[i++] = '-'; + 3fa: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 3ff: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 401: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 406: 8b 7d b8 mov -0x48(%ebp),%edi + 409: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 40d: eb 07 jmp 416 + 40f: 90 nop + putc(fd, buf[i]); + 410: 0f b6 13 movzbl (%ebx),%edx + 413: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 416: 83 ec 04 sub $0x4,%esp + 419: 88 55 d7 mov %dl,-0x29(%ebp) + 41c: 6a 01 push $0x1 + 41e: 56 push %esi + 41f: 57 push %edi + 420: e8 2e ff ff ff call 353 + while (--i >= 0) { + 425: 83 c4 10 add $0x10,%esp + 428: 39 de cmp %ebx,%esi + 42a: 75 e4 jne 410 + } +} + 42c: 8d 65 f4 lea -0xc(%ebp),%esp + 42f: 5b pop %ebx + 430: 5e pop %esi + 431: 5f pop %edi + 432: 5d pop %ebp + 433: c3 ret + 434: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 438: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 43f: eb 87 jmp 3c8 + 441: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 448: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 44f: 90 nop + +00000450 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 450: 55 push %ebp + 451: 89 e5 mov %esp,%ebp + 453: 57 push %edi + 454: 56 push %esi + 455: 53 push %ebx + 456: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 459: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 45c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 45f: 0f b6 13 movzbl (%ebx),%edx + 462: 84 d2 test %dl,%dl + 464: 74 6a je 4d0 + ap = (uint*)(void*)&fmt + 1; + 466: 8d 45 10 lea 0x10(%ebp),%eax + 469: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 46c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 46f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 471: 89 45 d0 mov %eax,-0x30(%ebp) + 474: eb 36 jmp 4ac + 476: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 47d: 8d 76 00 lea 0x0(%esi),%esi + 480: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 483: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 488: 83 f8 25 cmp $0x25,%eax + 48b: 74 15 je 4a2 + write(fd, &c, 1); + 48d: 83 ec 04 sub $0x4,%esp + 490: 88 55 e7 mov %dl,-0x19(%ebp) + 493: 6a 01 push $0x1 + 495: 57 push %edi + 496: 56 push %esi + 497: e8 b7 fe ff ff call 353 + 49c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 49f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 4a2: 0f b6 13 movzbl (%ebx),%edx + 4a5: 83 c3 01 add $0x1,%ebx + 4a8: 84 d2 test %dl,%dl + 4aa: 74 24 je 4d0 + c = fmt[i] & 0xff; + 4ac: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 4af: 85 c9 test %ecx,%ecx + 4b1: 74 cd je 480 + } + } + else if (state == '%') { + 4b3: 83 f9 25 cmp $0x25,%ecx + 4b6: 75 ea jne 4a2 + if (c == 'd') { + 4b8: 83 f8 25 cmp $0x25,%eax + 4bb: 0f 84 07 01 00 00 je 5c8 + 4c1: 83 e8 63 sub $0x63,%eax + 4c4: 83 f8 15 cmp $0x15,%eax + 4c7: 77 17 ja 4e0 + 4c9: ff 24 85 a4 07 00 00 jmp *0x7a4(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 4d0: 8d 65 f4 lea -0xc(%ebp),%esp + 4d3: 5b pop %ebx + 4d4: 5e pop %esi + 4d5: 5f pop %edi + 4d6: 5d pop %ebp + 4d7: c3 ret + 4d8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4df: 90 nop + write(fd, &c, 1); + 4e0: 83 ec 04 sub $0x4,%esp + 4e3: 88 55 d4 mov %dl,-0x2c(%ebp) + 4e6: 6a 01 push $0x1 + 4e8: 57 push %edi + 4e9: 56 push %esi + 4ea: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 4ee: e8 60 fe ff ff call 353 + putc(fd, c); + 4f3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 4f7: 83 c4 0c add $0xc,%esp + 4fa: 88 55 e7 mov %dl,-0x19(%ebp) + 4fd: 6a 01 push $0x1 + 4ff: 57 push %edi + 500: 56 push %esi + 501: e8 4d fe ff ff call 353 + putc(fd, c); + 506: 83 c4 10 add $0x10,%esp + state = 0; + 509: 31 c9 xor %ecx,%ecx + 50b: eb 95 jmp 4a2 + 50d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 510: 83 ec 0c sub $0xc,%esp + 513: b9 10 00 00 00 mov $0x10,%ecx + 518: 6a 00 push $0x0 + 51a: 8b 45 d0 mov -0x30(%ebp),%eax + 51d: 8b 10 mov (%eax),%edx + 51f: 89 f0 mov %esi,%eax + 521: e8 7a fe ff ff call 3a0 + ap++; + 526: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 52a: 83 c4 10 add $0x10,%esp + state = 0; + 52d: 31 c9 xor %ecx,%ecx + 52f: e9 6e ff ff ff jmp 4a2 + 534: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 538: 8b 45 d0 mov -0x30(%ebp),%eax + 53b: 8b 10 mov (%eax),%edx + ap++; + 53d: 83 c0 04 add $0x4,%eax + 540: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 543: 85 d2 test %edx,%edx + 545: 0f 84 8d 00 00 00 je 5d8 + while (*s != 0) { + 54b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 54e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 550: 84 c0 test %al,%al + 552: 0f 84 4a ff ff ff je 4a2 + 558: 89 5d d4 mov %ebx,-0x2c(%ebp) + 55b: 89 d3 mov %edx,%ebx + 55d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 560: 83 ec 04 sub $0x4,%esp + s++; + 563: 83 c3 01 add $0x1,%ebx + 566: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 569: 6a 01 push $0x1 + 56b: 57 push %edi + 56c: 56 push %esi + 56d: e8 e1 fd ff ff call 353 + while (*s != 0) { + 572: 0f b6 03 movzbl (%ebx),%eax + 575: 83 c4 10 add $0x10,%esp + 578: 84 c0 test %al,%al + 57a: 75 e4 jne 560 + state = 0; + 57c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 57f: 31 c9 xor %ecx,%ecx + 581: e9 1c ff ff ff jmp 4a2 + 586: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 58d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 590: 83 ec 0c sub $0xc,%esp + 593: b9 0a 00 00 00 mov $0xa,%ecx + 598: 6a 01 push $0x1 + 59a: e9 7b ff ff ff jmp 51a + 59f: 90 nop + putc(fd, *ap); + 5a0: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 5a3: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 5a6: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 5a8: 6a 01 push $0x1 + 5aa: 57 push %edi + 5ab: 56 push %esi + putc(fd, *ap); + 5ac: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 5af: e8 9f fd ff ff call 353 + ap++; + 5b4: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 5b8: 83 c4 10 add $0x10,%esp + state = 0; + 5bb: 31 c9 xor %ecx,%ecx + 5bd: e9 e0 fe ff ff jmp 4a2 + 5c2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 5c8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 5cb: 83 ec 04 sub $0x4,%esp + 5ce: e9 2a ff ff ff jmp 4fd + 5d3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 5d7: 90 nop + s = "(null)"; + 5d8: ba 9c 07 00 00 mov $0x79c,%edx + while (*s != 0) { + 5dd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 5e0: b8 28 00 00 00 mov $0x28,%eax + 5e5: 89 d3 mov %edx,%ebx + 5e7: e9 74 ff ff ff jmp 560 + 5ec: 66 90 xchg %ax,%ax + 5ee: 66 90 xchg %ax,%ax + +000005f0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 5f0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5f1: a1 b0 0a 00 00 mov 0xab0,%eax +void free(void *ap) { + 5f6: 89 e5 mov %esp,%ebp + 5f8: 57 push %edi + 5f9: 56 push %esi + 5fa: 53 push %ebx + 5fb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 5fe: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 601: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 608: 89 c2 mov %eax,%edx + 60a: 8b 00 mov (%eax),%eax + 60c: 39 ca cmp %ecx,%edx + 60e: 73 30 jae 640 + 610: 39 c1 cmp %eax,%ecx + 612: 72 04 jb 618 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 614: 39 c2 cmp %eax,%edx + 616: 72 f0 jb 608 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 618: 8b 73 fc mov -0x4(%ebx),%esi + 61b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 61e: 39 f8 cmp %edi,%eax + 620: 74 30 je 652 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 622: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 625: 8b 42 04 mov 0x4(%edx),%eax + 628: 8d 34 c2 lea (%edx,%eax,8),%esi + 62b: 39 f1 cmp %esi,%ecx + 62d: 74 3a je 669 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 62f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 631: 5b pop %ebx + freep = p; + 632: 89 15 b0 0a 00 00 mov %edx,0xab0 +} + 638: 5e pop %esi + 639: 5f pop %edi + 63a: 5d pop %ebp + 63b: c3 ret + 63c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 640: 39 c2 cmp %eax,%edx + 642: 72 c4 jb 608 + 644: 39 c1 cmp %eax,%ecx + 646: 73 c0 jae 608 + if (bp + bp->s.size == p->s.ptr) { + 648: 8b 73 fc mov -0x4(%ebx),%esi + 64b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 64e: 39 f8 cmp %edi,%eax + 650: 75 d0 jne 622 + bp->s.size += p->s.ptr->s.size; + 652: 03 70 04 add 0x4(%eax),%esi + 655: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 658: 8b 02 mov (%edx),%eax + 65a: 8b 00 mov (%eax),%eax + 65c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 65f: 8b 42 04 mov 0x4(%edx),%eax + 662: 8d 34 c2 lea (%edx,%eax,8),%esi + 665: 39 f1 cmp %esi,%ecx + 667: 75 c6 jne 62f + p->s.size += bp->s.size; + 669: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 66c: 89 15 b0 0a 00 00 mov %edx,0xab0 + p->s.size += bp->s.size; + 672: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 675: 8b 4b f8 mov -0x8(%ebx),%ecx + 678: 89 0a mov %ecx,(%edx) +} + 67a: 5b pop %ebx + 67b: 5e pop %esi + 67c: 5f pop %edi + 67d: 5d pop %ebp + 67e: c3 ret + 67f: 90 nop + +00000680 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 680: 55 push %ebp + 681: 89 e5 mov %esp,%ebp + 683: 57 push %edi + 684: 56 push %esi + 685: 53 push %ebx + 686: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 689: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 68c: 8b 3d b0 0a 00 00 mov 0xab0,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 692: 8d 70 07 lea 0x7(%eax),%esi + 695: c1 ee 03 shr $0x3,%esi + 698: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 69b: 85 ff test %edi,%edi + 69d: 0f 84 9d 00 00 00 je 740 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6a3: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 6a5: 8b 4a 04 mov 0x4(%edx),%ecx + 6a8: 39 f1 cmp %esi,%ecx + 6aa: 73 6a jae 716 + 6ac: bb 00 10 00 00 mov $0x1000,%ebx + 6b1: 39 de cmp %ebx,%esi + 6b3: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 6b6: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 6bd: 89 45 e4 mov %eax,-0x1c(%ebp) + 6c0: eb 17 jmp 6d9 + 6c2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6c8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 6ca: 8b 48 04 mov 0x4(%eax),%ecx + 6cd: 39 f1 cmp %esi,%ecx + 6cf: 73 4f jae 720 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 6d1: 8b 3d b0 0a 00 00 mov 0xab0,%edi + 6d7: 89 c2 mov %eax,%edx + 6d9: 39 d7 cmp %edx,%edi + 6db: 75 eb jne 6c8 + p = sbrk(nu * sizeof(Header)); + 6dd: 83 ec 0c sub $0xc,%esp + 6e0: ff 75 e4 push -0x1c(%ebp) + 6e3: e8 4b fc ff ff call 333 + if (p == (char*)-1) { + 6e8: 83 c4 10 add $0x10,%esp + 6eb: 83 f8 ff cmp $0xffffffff,%eax + 6ee: 74 1c je 70c + hp->s.size = nu; + 6f0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 6f3: 83 ec 0c sub $0xc,%esp + 6f6: 83 c0 08 add $0x8,%eax + 6f9: 50 push %eax + 6fa: e8 f1 fe ff ff call 5f0 + return freep; + 6ff: 8b 15 b0 0a 00 00 mov 0xab0,%edx + if ((p = morecore(nunits)) == 0) { + 705: 83 c4 10 add $0x10,%esp + 708: 85 d2 test %edx,%edx + 70a: 75 bc jne 6c8 + return 0; + } + } + } +} + 70c: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 70f: 31 c0 xor %eax,%eax +} + 711: 5b pop %ebx + 712: 5e pop %esi + 713: 5f pop %edi + 714: 5d pop %ebp + 715: c3 ret + if (p->s.size >= nunits) { + 716: 89 d0 mov %edx,%eax + 718: 89 fa mov %edi,%edx + 71a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 720: 39 ce cmp %ecx,%esi + 722: 74 4c je 770 + p->s.size -= nunits; + 724: 29 f1 sub %esi,%ecx + 726: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 729: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 72c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 72f: 89 15 b0 0a 00 00 mov %edx,0xab0 +} + 735: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 738: 83 c0 08 add $0x8,%eax +} + 73b: 5b pop %ebx + 73c: 5e pop %esi + 73d: 5f pop %edi + 73e: 5d pop %ebp + 73f: c3 ret + base.s.ptr = freep = prevp = &base; + 740: c7 05 b0 0a 00 00 b4 movl $0xab4,0xab0 + 747: 0a 00 00 + base.s.size = 0; + 74a: bf b4 0a 00 00 mov $0xab4,%edi + base.s.ptr = freep = prevp = &base; + 74f: c7 05 b4 0a 00 00 b4 movl $0xab4,0xab4 + 756: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 759: 89 fa mov %edi,%edx + base.s.size = 0; + 75b: c7 05 b8 0a 00 00 00 movl $0x0,0xab8 + 762: 00 00 00 + if (p->s.size >= nunits) { + 765: e9 42 ff ff ff jmp 6ac + 76a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 770: 8b 08 mov (%eax),%ecx + 772: 89 0a mov %ecx,(%edx) + 774: eb b9 jmp 72f diff --git a/shutdown.c b/shutdown.c new file mode 100644 index 0000000..8c7fa26 --- /dev/null +++ b/shutdown.c @@ -0,0 +1,24 @@ +#include "types.h" +#include "user.h" + +int main(int argc, char *argv[]) { + int restart = 0; + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-r") == 0) { + restart = 1; + } + } + + switch(restart) { + case 0: + printf(1, "Shutting Down...\n"); + break; + case 1: + printf(1, "Restarting...\n"); + break; + } + + shutdown(restart); + exit(); +} \ No newline at end of file diff --git a/shutdown.d b/shutdown.d new file mode 100644 index 0000000..a21cde4 --- /dev/null +++ b/shutdown.d @@ -0,0 +1 @@ +shutdown.o: shutdown.c /usr/include/stdc-predef.h types.h user.h diff --git a/shutdown.o b/shutdown.o new file mode 100644 index 0000000..9cdb23e Binary files /dev/null and b/shutdown.o differ diff --git a/shutdown.sym b/shutdown.sym new file mode 100644 index 0000000..17cd6c0 --- /dev/null +++ b/shutdown.sym @@ -0,0 +1,48 @@ +00000000 shutdown.c +00000000 ulib.c +00000000 printf.c +000003a0 printint +000007fc digits.0 +00000000 umalloc.c +00000ab0 freep +00000ab4 base +00000090 strcpy +00000450 printf +0000038b greeting +000002b0 memmove +0000035b mknod +000001b0 gets +0000032b getpid +00000680 malloc +0000033b sleep +000002f3 pipe +00000383 getch +00000353 write +00000313 fstat +00000303 kill +0000031b chdir +0000030b exec +000002eb wait +000002fb read +00000363 unlink +000002db fork +00000333 sbrk +00000343 uptime +00000ab0 __bss_start +00000150 memset +00000000 main +000000c0 strcmp +00000393 shutdown +00000323 dup +00000220 stat +00000ab0 _edata +00000abc _end +0000036b link +000002e3 exit +00000270 atoi +00000120 strlen +0000034b open +00000170 strchr +00000373 mkdir +0000037b close +000005f0 free diff --git a/sign.pl b/sign.pl new file mode 100644 index 0000000..d793035 --- /dev/null +++ b/sign.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; + +$n = sysread(SIG, $buf, 1000); + +if($n > 510){ + print STDERR "boot block too large: $n bytes (max 510)\n"; + exit 1; +} + +print STDERR "boot block is $n bytes (max 510)\n"; + +$buf .= "\0" x (510-$n); +$buf .= "\x55\xAA"; + +open(SIG, ">$ARGV[0]") || die "open >$ARGV[0]: $!"; +print SIG $buf; +close SIG; diff --git a/sleeplock.c b/sleeplock.c new file mode 100644 index 0000000..f45e910 --- /dev/null +++ b/sleeplock.c @@ -0,0 +1,48 @@ +// Sleeping locks + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "x86.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "spinlock.h" +#include "sleeplock.h" + +void initsleeplock(struct sleeplock *lk, char *name) { + initlock(&lk->lk, "sleep lock"); + lk->name = name; + lk->locked = 0; + lk->pid = 0; +} + +void acquiresleep(struct sleeplock *lk) { + acquire(&lk->lk); + while (lk->locked) { + sleep(lk, &lk->lk); + } + lk->locked = 1; + lk->pid = myproc()->pid; + release(&lk->lk); +} + +void releasesleep(struct sleeplock *lk) { + acquire(&lk->lk); + lk->locked = 0; + lk->pid = 0; + wakeup(lk); + release(&lk->lk); +} + +int holdingsleep(struct sleeplock *lk) { + int r; + + acquire(&lk->lk); + r = lk->locked && (lk->pid == myproc()->pid); + release(&lk->lk); + return r; +} + + + diff --git a/sleeplock.d b/sleeplock.d new file mode 100644 index 0000000..e50551a --- /dev/null +++ b/sleeplock.d @@ -0,0 +1,2 @@ +sleeplock.o: sleeplock.c /usr/include/stdc-predef.h types.h defs.h \ + param.h x86.h memlayout.h mmu.h proc.h spinlock.h sleeplock.h diff --git a/sleeplock.h b/sleeplock.h new file mode 100644 index 0000000..832e871 --- /dev/null +++ b/sleeplock.h @@ -0,0 +1,10 @@ +// Long-term locks for processes +struct sleeplock { + uint locked; // Is the lock held? + struct spinlock lk; // spinlock protecting this sleep lock + + // For debugging: + char *name; // Name of lock. + int pid; // Process holding lock +}; + diff --git a/sleeplock.o b/sleeplock.o new file mode 100644 index 0000000..ba2e7e9 Binary files /dev/null and b/sleeplock.o differ diff --git a/spinlock.c b/spinlock.c new file mode 100644 index 0000000..f0b345f --- /dev/null +++ b/spinlock.c @@ -0,0 +1,121 @@ +// Mutual exclusion spin locks. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "x86.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "spinlock.h" + +void initlock(struct spinlock *lk, char *name) { + lk->name = name; + lk->locked = 0; + lk->cpu = 0; +} + +// Acquire the lock. +// Loops (spins) until the lock is acquired. +// Holding a lock for a long time may cause +// other CPUs to waste time spinning to acquire it. +void acquire(struct spinlock *lk) { + pushcli(); // disable interrupts to avoid deadlock. + if (holding(lk)) { + panic("acquire"); + } + + // The xchg is atomic. + while (xchg(&lk->locked, 1) != 0) { + ; + } + + // Tell the C compiler and the processor to not move loads or stores + // past this point, to ensure that the critical section's memory + // references happen after the lock is acquired. + __sync_synchronize(); + + // Record info about lock acquisition for debugging. + lk->cpu = mycpu(); + getcallerpcs(&lk, lk->pcs); +} + +// Release the lock. +void release(struct spinlock *lk) { + if (!holding(lk)) { + panic("release"); + } + + lk->pcs[0] = 0; + lk->cpu = 0; + + // Tell the C compiler and the processor to not move loads or stores + // past this point, to ensure that all the stores in the critical + // section are visible to other cores before the lock is released. + // Both the C compiler and the hardware may re-order loads and + // stores; __sync_synchronize() tells them both not to. + __sync_synchronize(); + + // Release the lock, equivalent to lk->locked = 0. + // This code can't use a C assignment, since it might + // not be atomic. A real OS would use C atomics here. + asm volatile ("movl $0, %0" : "+m" (lk->locked) :); + + popcli(); +} + +// Record the current call stack in pcs[] by following the %ebp chain. +void getcallerpcs(void *v, uint pcs[]) { + uint *ebp; + int i; + + ebp = (uint*)v - 2; + for (i = 0; i < 10; i++) { + if (ebp == 0 || ebp < (uint*)KERNBASE || ebp == (uint*)0xffffffff) { + break; + } + pcs[i] = ebp[1]; // saved %eip + ebp = (uint*)ebp[0]; // saved %ebp + } + for (; i < 10; i++) { + pcs[i] = 0; + } +} + +// Check whether this cpu is holding the lock. +int holding(struct spinlock *lock) { + int r; + pushcli(); + r = lock->locked && lock->cpu == mycpu(); + popcli(); + return r; +} + + +// Pushcli/popcli are like cli/sti except that they are matched: +// it takes two popcli to undo two pushcli. Also, if interrupts +// are off, then pushcli, popcli leaves them off. + +void pushcli(void) { + int eflags; + + eflags = readeflags(); + cli(); + if (mycpu()->ncli == 0) { + mycpu()->intena = eflags & FL_IF; + } + mycpu()->ncli += 1; +} + +void popcli(void) { + if (readeflags() & FL_IF) { + panic("popcli - interruptible"); + } + if (--mycpu()->ncli < 0) { + panic("popcli"); + } + if (mycpu()->ncli == 0 && mycpu()->intena) { + sti(); + } +} + diff --git a/spinlock.d b/spinlock.d new file mode 100644 index 0000000..9f70952 --- /dev/null +++ b/spinlock.d @@ -0,0 +1,2 @@ +spinlock.o: spinlock.c /usr/include/stdc-predef.h types.h defs.h param.h \ + x86.h memlayout.h mmu.h proc.h spinlock.h diff --git a/spinlock.h b/spinlock.h new file mode 100644 index 0000000..d719bac --- /dev/null +++ b/spinlock.h @@ -0,0 +1,11 @@ +// Mutual exclusion lock. +struct spinlock { + uint locked; // Is the lock held? + + // For debugging: + char *name; // Name of lock. + struct cpu *cpu; // The cpu holding the lock. + uint pcs[10]; // The call stack (an array of program counters) + // that locked the lock. +}; + diff --git a/spinlock.o b/spinlock.o new file mode 100644 index 0000000..432e5bc Binary files /dev/null and b/spinlock.o differ diff --git a/stat.h b/stat.h new file mode 100644 index 0000000..e54ba86 --- /dev/null +++ b/stat.h @@ -0,0 +1,11 @@ +#define T_DIR 1 // Directory +#define T_FILE 2 // File +#define T_DEV 3 // Device + +struct stat { + short type; // Type of file + int dev; // File system's disk device + uint ino; // Inode number + short nlink; // Number of links to file + uint size; // Size of file in bytes +}; diff --git a/stressfs.asm b/stressfs.asm new file mode 100644 index 0000000..82e475b --- /dev/null +++ b/stressfs.asm @@ -0,0 +1,1276 @@ + +_stressfs: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +#include "stat.h" +#include "user.h" +#include "fs.h" +#include "fcntl.h" + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + int fd, i; + char path[] = "stressfs0"; + 7: b8 30 00 00 00 mov $0x30,%eax +int main(int argc, char *argv[]) { + c: ff 71 fc push -0x4(%ecx) + f: 55 push %ebp + 10: 89 e5 mov %esp,%ebp + 12: 57 push %edi + 13: 56 push %esi + char data[512]; + + printf(1, "stressfs starting\n"); + memset(data, 'a', sizeof(data)); + 14: 8d b5 e8 fd ff ff lea -0x218(%ebp),%esi +int main(int argc, char *argv[]) { + 1a: 53 push %ebx + + for (i = 0; i < 4; i++) { + 1b: 31 db xor %ebx,%ebx +int main(int argc, char *argv[]) { + 1d: 51 push %ecx + 1e: 81 ec 20 02 00 00 sub $0x220,%esp + char path[] = "stressfs0"; + 24: 66 89 85 e6 fd ff ff mov %ax,-0x21a(%ebp) + printf(1, "stressfs starting\n"); + 2b: 68 28 08 00 00 push $0x828 + 30: 6a 01 push $0x1 + char path[] = "stressfs0"; + 32: c7 85 de fd ff ff 73 movl $0x65727473,-0x222(%ebp) + 39: 74 72 65 + 3c: c7 85 e2 fd ff ff 73 movl $0x73667373,-0x21e(%ebp) + 43: 73 66 73 + printf(1, "stressfs starting\n"); + 46: e8 b5 04 00 00 call 500 + memset(data, 'a', sizeof(data)); + 4b: 83 c4 0c add $0xc,%esp + 4e: 68 00 02 00 00 push $0x200 + 53: 6a 61 push $0x61 + 55: 56 push %esi + 56: e8 a5 01 00 00 call 200 + 5b: 83 c4 10 add $0x10,%esp + if (fork() > 0) { + 5e: e8 28 03 00 00 call 38b + 63: 85 c0 test %eax,%eax + 65: 0f 8f bf 00 00 00 jg 12a + for (i = 0; i < 4; i++) { + 6b: 83 c3 01 add $0x1,%ebx + 6e: 83 fb 04 cmp $0x4,%ebx + 71: 75 eb jne 5e + 73: bf 04 00 00 00 mov $0x4,%edi + break; + } + } + + printf(1, "write %d\n", i); + 78: 83 ec 04 sub $0x4,%esp + 7b: 53 push %ebx + + path[8] += i; + fd = open(path, O_CREATE | O_RDWR); + 7c: bb 14 00 00 00 mov $0x14,%ebx + printf(1, "write %d\n", i); + 81: 68 3b 08 00 00 push $0x83b + 86: 6a 01 push $0x1 + 88: e8 73 04 00 00 call 500 + path[8] += i; + 8d: 89 f8 mov %edi,%eax + fd = open(path, O_CREATE | O_RDWR); + 8f: 5f pop %edi + path[8] += i; + 90: 00 85 e6 fd ff ff add %al,-0x21a(%ebp) + fd = open(path, O_CREATE | O_RDWR); + 96: 58 pop %eax + 97: 8d 85 de fd ff ff lea -0x222(%ebp),%eax + 9d: 68 02 02 00 00 push $0x202 + a2: 50 push %eax + a3: e8 53 03 00 00 call 3fb + a8: 83 c4 10 add $0x10,%esp + ab: 89 c7 mov %eax,%edi + for (i = 0; i < 20; i++) { + ad: 8d 76 00 lea 0x0(%esi),%esi +// printf(fd, "%d\n", i); + write(fd, data, sizeof(data)); + b0: 83 ec 04 sub $0x4,%esp + b3: 68 00 02 00 00 push $0x200 + b8: 56 push %esi + b9: 57 push %edi + ba: e8 44 03 00 00 call 403 + for (i = 0; i < 20; i++) { + bf: 83 c4 10 add $0x10,%esp + c2: 83 eb 01 sub $0x1,%ebx + c5: 75 e9 jne b0 + } + close(fd); + c7: 83 ec 0c sub $0xc,%esp + ca: 57 push %edi + cb: e8 5b 03 00 00 call 42b + + printf(1, "read\n"); + d0: 58 pop %eax + d1: 5a pop %edx + d2: 68 45 08 00 00 push $0x845 + d7: 6a 01 push $0x1 + d9: e8 22 04 00 00 call 500 + + fd = open(path, O_RDONLY); + de: 8d 85 de fd ff ff lea -0x222(%ebp),%eax + e4: 59 pop %ecx + e5: 5b pop %ebx + e6: 6a 00 push $0x0 + e8: bb 14 00 00 00 mov $0x14,%ebx + ed: 50 push %eax + ee: e8 08 03 00 00 call 3fb + f3: 83 c4 10 add $0x10,%esp + f6: 89 c7 mov %eax,%edi + for (i = 0; i < 20; i++) { + f8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + ff: 90 nop + read(fd, data, sizeof(data)); + 100: 83 ec 04 sub $0x4,%esp + 103: 68 00 02 00 00 push $0x200 + 108: 56 push %esi + 109: 57 push %edi + 10a: e8 9c 02 00 00 call 3ab + for (i = 0; i < 20; i++) { + 10f: 83 c4 10 add $0x10,%esp + 112: 83 eb 01 sub $0x1,%ebx + 115: 75 e9 jne 100 + } + close(fd); + 117: 83 ec 0c sub $0xc,%esp + 11a: 57 push %edi + 11b: e8 0b 03 00 00 call 42b + + wait(); + 120: e8 76 02 00 00 call 39b + + exit(); + 125: e8 69 02 00 00 call 393 + path[8] += i; + 12a: 89 df mov %ebx,%edi + 12c: e9 47 ff ff ff jmp 78 + 131: 66 90 xchg %ax,%ax + 133: 66 90 xchg %ax,%ax + 135: 66 90 xchg %ax,%ax + 137: 66 90 xchg %ax,%ax + 139: 66 90 xchg %ax,%ax + 13b: 66 90 xchg %ax,%ax + 13d: 66 90 xchg %ax,%ax + 13f: 90 nop + +00000140 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 140: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 141: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 143: 89 e5 mov %esp,%ebp + 145: 53 push %ebx + 146: 8b 4d 08 mov 0x8(%ebp),%ecx + 149: 8b 5d 0c mov 0xc(%ebp),%ebx + 14c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 150: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 154: 88 14 01 mov %dl,(%ecx,%eax,1) + 157: 83 c0 01 add $0x1,%eax + 15a: 84 d2 test %dl,%dl + 15c: 75 f2 jne 150 + ; + } + return os; +} + 15e: 8b 5d fc mov -0x4(%ebp),%ebx + 161: 89 c8 mov %ecx,%eax + 163: c9 leave + 164: c3 ret + 165: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 16c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000170 : + +int strcmp(const char *p, const char *q) { + 170: 55 push %ebp + 171: 89 e5 mov %esp,%ebp + 173: 53 push %ebx + 174: 8b 55 08 mov 0x8(%ebp),%edx + 177: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 17a: 0f b6 02 movzbl (%edx),%eax + 17d: 84 c0 test %al,%al + 17f: 75 17 jne 198 + 181: eb 3a jmp 1bd + 183: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 187: 90 nop + 188: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 18c: 83 c2 01 add $0x1,%edx + 18f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 192: 84 c0 test %al,%al + 194: 74 1a je 1b0 + p++, q++; + 196: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 198: 0f b6 19 movzbl (%ecx),%ebx + 19b: 38 c3 cmp %al,%bl + 19d: 74 e9 je 188 + } + return (uchar) * p - (uchar) * q; + 19f: 29 d8 sub %ebx,%eax +} + 1a1: 8b 5d fc mov -0x4(%ebp),%ebx + 1a4: c9 leave + 1a5: c3 ret + 1a6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ad: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 1b0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 1b4: 31 c0 xor %eax,%eax + 1b6: 29 d8 sub %ebx,%eax +} + 1b8: 8b 5d fc mov -0x4(%ebp),%ebx + 1bb: c9 leave + 1bc: c3 ret + return (uchar) * p - (uchar) * q; + 1bd: 0f b6 19 movzbl (%ecx),%ebx + 1c0: 31 c0 xor %eax,%eax + 1c2: eb db jmp 19f + 1c4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1cb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1cf: 90 nop + +000001d0 : + +uint strlen(const char *s) { + 1d0: 55 push %ebp + 1d1: 89 e5 mov %esp,%ebp + 1d3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 1d6: 80 3a 00 cmpb $0x0,(%edx) + 1d9: 74 15 je 1f0 + 1db: 31 c0 xor %eax,%eax + 1dd: 8d 76 00 lea 0x0(%esi),%esi + 1e0: 83 c0 01 add $0x1,%eax + 1e3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 1e7: 89 c1 mov %eax,%ecx + 1e9: 75 f5 jne 1e0 + ; + } + return n; +} + 1eb: 89 c8 mov %ecx,%eax + 1ed: 5d pop %ebp + 1ee: c3 ret + 1ef: 90 nop + for (n = 0; s[n]; n++) { + 1f0: 31 c9 xor %ecx,%ecx +} + 1f2: 5d pop %ebp + 1f3: 89 c8 mov %ecx,%eax + 1f5: c3 ret + 1f6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1fd: 8d 76 00 lea 0x0(%esi),%esi + +00000200 : + +void* memset(void *dst, int c, uint n) { + 200: 55 push %ebp + 201: 89 e5 mov %esp,%ebp + 203: 57 push %edi + 204: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 207: 8b 4d 10 mov 0x10(%ebp),%ecx + 20a: 8b 45 0c mov 0xc(%ebp),%eax + 20d: 89 d7 mov %edx,%edi + 20f: fc cld + 210: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 212: 8b 7d fc mov -0x4(%ebp),%edi + 215: 89 d0 mov %edx,%eax + 217: c9 leave + 218: c3 ret + 219: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000220 : + +char* strchr(const char *s, char c) { + 220: 55 push %ebp + 221: 89 e5 mov %esp,%ebp + 223: 8b 45 08 mov 0x8(%ebp),%eax + 226: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 22a: 0f b6 10 movzbl (%eax),%edx + 22d: 84 d2 test %dl,%dl + 22f: 75 12 jne 243 + 231: eb 1d jmp 250 + 233: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 237: 90 nop + 238: 0f b6 50 01 movzbl 0x1(%eax),%edx + 23c: 83 c0 01 add $0x1,%eax + 23f: 84 d2 test %dl,%dl + 241: 74 0d je 250 + if (*s == c) { + 243: 38 d1 cmp %dl,%cl + 245: 75 f1 jne 238 + return (char*)s; + } + } + return 0; +} + 247: 5d pop %ebp + 248: c3 ret + 249: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 250: 31 c0 xor %eax,%eax +} + 252: 5d pop %ebp + 253: c3 ret + 254: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 25b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 25f: 90 nop + +00000260 : + +char* gets(char *buf, int max) { + 260: 55 push %ebp + 261: 89 e5 mov %esp,%ebp + 263: 57 push %edi + 264: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 265: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 268: 53 push %ebx + for (i = 0; i + 1 < max;) { + 269: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 26b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 26e: eb 27 jmp 297 + cc = read(0, &c, 1); + 270: 83 ec 04 sub $0x4,%esp + 273: 6a 01 push $0x1 + 275: 57 push %edi + 276: 6a 00 push $0x0 + 278: e8 2e 01 00 00 call 3ab + if (cc < 1) { + 27d: 83 c4 10 add $0x10,%esp + 280: 85 c0 test %eax,%eax + 282: 7e 1d jle 2a1 + break; + } + buf[i++] = c; + 284: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 288: 8b 55 08 mov 0x8(%ebp),%edx + 28b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 28f: 3c 0a cmp $0xa,%al + 291: 74 1d je 2b0 + 293: 3c 0d cmp $0xd,%al + 295: 74 19 je 2b0 + for (i = 0; i + 1 < max;) { + 297: 89 de mov %ebx,%esi + 299: 83 c3 01 add $0x1,%ebx + 29c: 3b 5d 0c cmp 0xc(%ebp),%ebx + 29f: 7c cf jl 270 + break; + } + } + buf[i] = '\0'; + 2a1: 8b 45 08 mov 0x8(%ebp),%eax + 2a4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 2a8: 8d 65 f4 lea -0xc(%ebp),%esp + 2ab: 5b pop %ebx + 2ac: 5e pop %esi + 2ad: 5f pop %edi + 2ae: 5d pop %ebp + 2af: c3 ret + buf[i] = '\0'; + 2b0: 8b 45 08 mov 0x8(%ebp),%eax + 2b3: 89 de mov %ebx,%esi + 2b5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 2b9: 8d 65 f4 lea -0xc(%ebp),%esp + 2bc: 5b pop %ebx + 2bd: 5e pop %esi + 2be: 5f pop %edi + 2bf: 5d pop %ebp + 2c0: c3 ret + 2c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2cf: 90 nop + +000002d0 : + +int stat(const char *n, struct stat *st) { + 2d0: 55 push %ebp + 2d1: 89 e5 mov %esp,%ebp + 2d3: 56 push %esi + 2d4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 2d5: 83 ec 08 sub $0x8,%esp + 2d8: 6a 00 push $0x0 + 2da: ff 75 08 push 0x8(%ebp) + 2dd: e8 19 01 00 00 call 3fb + if (fd < 0) { + 2e2: 83 c4 10 add $0x10,%esp + 2e5: 85 c0 test %eax,%eax + 2e7: 78 27 js 310 + return -1; + } + r = fstat(fd, st); + 2e9: 83 ec 08 sub $0x8,%esp + 2ec: ff 75 0c push 0xc(%ebp) + 2ef: 89 c3 mov %eax,%ebx + 2f1: 50 push %eax + 2f2: e8 cc 00 00 00 call 3c3 + close(fd); + 2f7: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 2fa: 89 c6 mov %eax,%esi + close(fd); + 2fc: e8 2a 01 00 00 call 42b + return r; + 301: 83 c4 10 add $0x10,%esp +} + 304: 8d 65 f8 lea -0x8(%ebp),%esp + 307: 89 f0 mov %esi,%eax + 309: 5b pop %ebx + 30a: 5e pop %esi + 30b: 5d pop %ebp + 30c: c3 ret + 30d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 310: be ff ff ff ff mov $0xffffffff,%esi + 315: eb ed jmp 304 + 317: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 31e: 66 90 xchg %ax,%ax + +00000320 : + +int atoi(const char *s) { + 320: 55 push %ebp + 321: 89 e5 mov %esp,%ebp + 323: 53 push %ebx + 324: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 327: 0f be 02 movsbl (%edx),%eax + 32a: 8d 48 d0 lea -0x30(%eax),%ecx + 32d: 80 f9 09 cmp $0x9,%cl + n = 0; + 330: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 335: 77 1e ja 355 + 337: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 33e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 340: 83 c2 01 add $0x1,%edx + 343: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 346: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 34a: 0f be 02 movsbl (%edx),%eax + 34d: 8d 58 d0 lea -0x30(%eax),%ebx + 350: 80 fb 09 cmp $0x9,%bl + 353: 76 eb jbe 340 + } + return n; +} + 355: 8b 5d fc mov -0x4(%ebp),%ebx + 358: 89 c8 mov %ecx,%eax + 35a: c9 leave + 35b: c3 ret + 35c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000360 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 360: 55 push %ebp + 361: 89 e5 mov %esp,%ebp + 363: 57 push %edi + 364: 8b 45 10 mov 0x10(%ebp),%eax + 367: 8b 55 08 mov 0x8(%ebp),%edx + 36a: 56 push %esi + 36b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 36e: 85 c0 test %eax,%eax + 370: 7e 13 jle 385 + 372: 01 d0 add %edx,%eax + dst = vdst; + 374: 89 d7 mov %edx,%edi + 376: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 37d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 380: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 381: 39 f8 cmp %edi,%eax + 383: 75 fb jne 380 + } + return vdst; +} + 385: 5e pop %esi + 386: 89 d0 mov %edx,%eax + 388: 5f pop %edi + 389: 5d pop %ebp + 38a: c3 ret + +0000038b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 38b: b8 01 00 00 00 mov $0x1,%eax + 390: cd 40 int $0x40 + 392: c3 ret + +00000393 : +SYSCALL(exit) + 393: b8 02 00 00 00 mov $0x2,%eax + 398: cd 40 int $0x40 + 39a: c3 ret + +0000039b : +SYSCALL(wait) + 39b: b8 03 00 00 00 mov $0x3,%eax + 3a0: cd 40 int $0x40 + 3a2: c3 ret + +000003a3 : +SYSCALL(pipe) + 3a3: b8 04 00 00 00 mov $0x4,%eax + 3a8: cd 40 int $0x40 + 3aa: c3 ret + +000003ab : +SYSCALL(read) + 3ab: b8 05 00 00 00 mov $0x5,%eax + 3b0: cd 40 int $0x40 + 3b2: c3 ret + +000003b3 : +SYSCALL(kill) + 3b3: b8 06 00 00 00 mov $0x6,%eax + 3b8: cd 40 int $0x40 + 3ba: c3 ret + +000003bb : +SYSCALL(exec) + 3bb: b8 07 00 00 00 mov $0x7,%eax + 3c0: cd 40 int $0x40 + 3c2: c3 ret + +000003c3 : +SYSCALL(fstat) + 3c3: b8 08 00 00 00 mov $0x8,%eax + 3c8: cd 40 int $0x40 + 3ca: c3 ret + +000003cb : +SYSCALL(chdir) + 3cb: b8 09 00 00 00 mov $0x9,%eax + 3d0: cd 40 int $0x40 + 3d2: c3 ret + +000003d3 : +SYSCALL(dup) + 3d3: b8 0a 00 00 00 mov $0xa,%eax + 3d8: cd 40 int $0x40 + 3da: c3 ret + +000003db : +SYSCALL(getpid) + 3db: b8 0b 00 00 00 mov $0xb,%eax + 3e0: cd 40 int $0x40 + 3e2: c3 ret + +000003e3 : +SYSCALL(sbrk) + 3e3: b8 0c 00 00 00 mov $0xc,%eax + 3e8: cd 40 int $0x40 + 3ea: c3 ret + +000003eb : +SYSCALL(sleep) + 3eb: b8 0d 00 00 00 mov $0xd,%eax + 3f0: cd 40 int $0x40 + 3f2: c3 ret + +000003f3 : +SYSCALL(uptime) + 3f3: b8 0e 00 00 00 mov $0xe,%eax + 3f8: cd 40 int $0x40 + 3fa: c3 ret + +000003fb : +SYSCALL(open) + 3fb: b8 0f 00 00 00 mov $0xf,%eax + 400: cd 40 int $0x40 + 402: c3 ret + +00000403 : +SYSCALL(write) + 403: b8 10 00 00 00 mov $0x10,%eax + 408: cd 40 int $0x40 + 40a: c3 ret + +0000040b : +SYSCALL(mknod) + 40b: b8 11 00 00 00 mov $0x11,%eax + 410: cd 40 int $0x40 + 412: c3 ret + +00000413 : +SYSCALL(unlink) + 413: b8 12 00 00 00 mov $0x12,%eax + 418: cd 40 int $0x40 + 41a: c3 ret + +0000041b : +SYSCALL(link) + 41b: b8 13 00 00 00 mov $0x13,%eax + 420: cd 40 int $0x40 + 422: c3 ret + +00000423 : +SYSCALL(mkdir) + 423: b8 14 00 00 00 mov $0x14,%eax + 428: cd 40 int $0x40 + 42a: c3 ret + +0000042b : +SYSCALL(close) + 42b: b8 15 00 00 00 mov $0x15,%eax + 430: cd 40 int $0x40 + 432: c3 ret + +00000433 : +SYSCALL(getch) + 433: b8 16 00 00 00 mov $0x16,%eax + 438: cd 40 int $0x40 + 43a: c3 ret + +0000043b : +SYSCALL(greeting) + 43b: b8 17 00 00 00 mov $0x17,%eax + 440: cd 40 int $0x40 + 442: c3 ret + +00000443 : +SYSCALL(shutdown) + 443: b8 18 00 00 00 mov $0x18,%eax + 448: cd 40 int $0x40 + 44a: c3 ret + 44b: 66 90 xchg %ax,%ax + 44d: 66 90 xchg %ax,%ax + 44f: 90 nop + +00000450 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 450: 55 push %ebp + 451: 89 e5 mov %esp,%ebp + 453: 57 push %edi + 454: 56 push %esi + 455: 53 push %ebx + 456: 83 ec 3c sub $0x3c,%esp + 459: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 45c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 45e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 461: 85 d2 test %edx,%edx + 463: 0f 89 7f 00 00 00 jns 4e8 + 469: f6 45 08 01 testb $0x1,0x8(%ebp) + 46d: 74 79 je 4e8 + neg = 1; + 46f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 476: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 478: 31 db xor %ebx,%ebx + 47a: 8d 75 d7 lea -0x29(%ebp),%esi + 47d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 480: 89 c8 mov %ecx,%eax + 482: 31 d2 xor %edx,%edx + 484: 89 cf mov %ecx,%edi + 486: f7 75 c4 divl -0x3c(%ebp) + 489: 0f b6 92 ac 08 00 00 movzbl 0x8ac(%edx),%edx + 490: 89 45 c0 mov %eax,-0x40(%ebp) + 493: 89 d8 mov %ebx,%eax + 495: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 498: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 49b: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 49e: 39 7d c4 cmp %edi,-0x3c(%ebp) + 4a1: 76 dd jbe 480 + if (neg) { + 4a3: 8b 4d bc mov -0x44(%ebp),%ecx + 4a6: 85 c9 test %ecx,%ecx + 4a8: 74 0c je 4b6 + buf[i++] = '-'; + 4aa: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 4af: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 4b1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 4b6: 8b 7d b8 mov -0x48(%ebp),%edi + 4b9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 4bd: eb 07 jmp 4c6 + 4bf: 90 nop + putc(fd, buf[i]); + 4c0: 0f b6 13 movzbl (%ebx),%edx + 4c3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 4c6: 83 ec 04 sub $0x4,%esp + 4c9: 88 55 d7 mov %dl,-0x29(%ebp) + 4cc: 6a 01 push $0x1 + 4ce: 56 push %esi + 4cf: 57 push %edi + 4d0: e8 2e ff ff ff call 403 + while (--i >= 0) { + 4d5: 83 c4 10 add $0x10,%esp + 4d8: 39 de cmp %ebx,%esi + 4da: 75 e4 jne 4c0 + } +} + 4dc: 8d 65 f4 lea -0xc(%ebp),%esp + 4df: 5b pop %ebx + 4e0: 5e pop %esi + 4e1: 5f pop %edi + 4e2: 5d pop %ebp + 4e3: c3 ret + 4e4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 4e8: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 4ef: eb 87 jmp 478 + 4f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4f8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 4ff: 90 nop + +00000500 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 500: 55 push %ebp + 501: 89 e5 mov %esp,%ebp + 503: 57 push %edi + 504: 56 push %esi + 505: 53 push %ebx + 506: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 509: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 50c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 50f: 0f b6 13 movzbl (%ebx),%edx + 512: 84 d2 test %dl,%dl + 514: 74 6a je 580 + ap = (uint*)(void*)&fmt + 1; + 516: 8d 45 10 lea 0x10(%ebp),%eax + 519: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 51c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 51f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 521: 89 45 d0 mov %eax,-0x30(%ebp) + 524: eb 36 jmp 55c + 526: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 52d: 8d 76 00 lea 0x0(%esi),%esi + 530: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 533: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 538: 83 f8 25 cmp $0x25,%eax + 53b: 74 15 je 552 + write(fd, &c, 1); + 53d: 83 ec 04 sub $0x4,%esp + 540: 88 55 e7 mov %dl,-0x19(%ebp) + 543: 6a 01 push $0x1 + 545: 57 push %edi + 546: 56 push %esi + 547: e8 b7 fe ff ff call 403 + 54c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 54f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 552: 0f b6 13 movzbl (%ebx),%edx + 555: 83 c3 01 add $0x1,%ebx + 558: 84 d2 test %dl,%dl + 55a: 74 24 je 580 + c = fmt[i] & 0xff; + 55c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 55f: 85 c9 test %ecx,%ecx + 561: 74 cd je 530 + } + } + else if (state == '%') { + 563: 83 f9 25 cmp $0x25,%ecx + 566: 75 ea jne 552 + if (c == 'd') { + 568: 83 f8 25 cmp $0x25,%eax + 56b: 0f 84 07 01 00 00 je 678 + 571: 83 e8 63 sub $0x63,%eax + 574: 83 f8 15 cmp $0x15,%eax + 577: 77 17 ja 590 + 579: ff 24 85 54 08 00 00 jmp *0x854(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 580: 8d 65 f4 lea -0xc(%ebp),%esp + 583: 5b pop %ebx + 584: 5e pop %esi + 585: 5f pop %edi + 586: 5d pop %ebp + 587: c3 ret + 588: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 58f: 90 nop + write(fd, &c, 1); + 590: 83 ec 04 sub $0x4,%esp + 593: 88 55 d4 mov %dl,-0x2c(%ebp) + 596: 6a 01 push $0x1 + 598: 57 push %edi + 599: 56 push %esi + 59a: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 59e: e8 60 fe ff ff call 403 + putc(fd, c); + 5a3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 5a7: 83 c4 0c add $0xc,%esp + 5aa: 88 55 e7 mov %dl,-0x19(%ebp) + 5ad: 6a 01 push $0x1 + 5af: 57 push %edi + 5b0: 56 push %esi + 5b1: e8 4d fe ff ff call 403 + putc(fd, c); + 5b6: 83 c4 10 add $0x10,%esp + state = 0; + 5b9: 31 c9 xor %ecx,%ecx + 5bb: eb 95 jmp 552 + 5bd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 5c0: 83 ec 0c sub $0xc,%esp + 5c3: b9 10 00 00 00 mov $0x10,%ecx + 5c8: 6a 00 push $0x0 + 5ca: 8b 45 d0 mov -0x30(%ebp),%eax + 5cd: 8b 10 mov (%eax),%edx + 5cf: 89 f0 mov %esi,%eax + 5d1: e8 7a fe ff ff call 450 + ap++; + 5d6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 5da: 83 c4 10 add $0x10,%esp + state = 0; + 5dd: 31 c9 xor %ecx,%ecx + 5df: e9 6e ff ff ff jmp 552 + 5e4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 5e8: 8b 45 d0 mov -0x30(%ebp),%eax + 5eb: 8b 10 mov (%eax),%edx + ap++; + 5ed: 83 c0 04 add $0x4,%eax + 5f0: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 5f3: 85 d2 test %edx,%edx + 5f5: 0f 84 8d 00 00 00 je 688 + while (*s != 0) { + 5fb: 0f b6 02 movzbl (%edx),%eax + state = 0; + 5fe: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 600: 84 c0 test %al,%al + 602: 0f 84 4a ff ff ff je 552 + 608: 89 5d d4 mov %ebx,-0x2c(%ebp) + 60b: 89 d3 mov %edx,%ebx + 60d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 610: 83 ec 04 sub $0x4,%esp + s++; + 613: 83 c3 01 add $0x1,%ebx + 616: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 619: 6a 01 push $0x1 + 61b: 57 push %edi + 61c: 56 push %esi + 61d: e8 e1 fd ff ff call 403 + while (*s != 0) { + 622: 0f b6 03 movzbl (%ebx),%eax + 625: 83 c4 10 add $0x10,%esp + 628: 84 c0 test %al,%al + 62a: 75 e4 jne 610 + state = 0; + 62c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 62f: 31 c9 xor %ecx,%ecx + 631: e9 1c ff ff ff jmp 552 + 636: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 63d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 640: 83 ec 0c sub $0xc,%esp + 643: b9 0a 00 00 00 mov $0xa,%ecx + 648: 6a 01 push $0x1 + 64a: e9 7b ff ff ff jmp 5ca + 64f: 90 nop + putc(fd, *ap); + 650: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 653: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 656: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 658: 6a 01 push $0x1 + 65a: 57 push %edi + 65b: 56 push %esi + putc(fd, *ap); + 65c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 65f: e8 9f fd ff ff call 403 + ap++; + 664: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 668: 83 c4 10 add $0x10,%esp + state = 0; + 66b: 31 c9 xor %ecx,%ecx + 66d: e9 e0 fe ff ff jmp 552 + 672: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 678: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 67b: 83 ec 04 sub $0x4,%esp + 67e: e9 2a ff ff ff jmp 5ad + 683: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 687: 90 nop + s = "(null)"; + 688: ba 4b 08 00 00 mov $0x84b,%edx + while (*s != 0) { + 68d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 690: b8 28 00 00 00 mov $0x28,%eax + 695: 89 d3 mov %edx,%ebx + 697: e9 74 ff ff ff jmp 610 + 69c: 66 90 xchg %ax,%ax + 69e: 66 90 xchg %ax,%ax + +000006a0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 6a0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 6a1: a1 64 0b 00 00 mov 0xb64,%eax +void free(void *ap) { + 6a6: 89 e5 mov %esp,%ebp + 6a8: 57 push %edi + 6a9: 56 push %esi + 6aa: 53 push %ebx + 6ab: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 6ae: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 6b1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 6b8: 89 c2 mov %eax,%edx + 6ba: 8b 00 mov (%eax),%eax + 6bc: 39 ca cmp %ecx,%edx + 6be: 73 30 jae 6f0 + 6c0: 39 c1 cmp %eax,%ecx + 6c2: 72 04 jb 6c8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 6c4: 39 c2 cmp %eax,%edx + 6c6: 72 f0 jb 6b8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 6c8: 8b 73 fc mov -0x4(%ebx),%esi + 6cb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 6ce: 39 f8 cmp %edi,%eax + 6d0: 74 30 je 702 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 6d2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 6d5: 8b 42 04 mov 0x4(%edx),%eax + 6d8: 8d 34 c2 lea (%edx,%eax,8),%esi + 6db: 39 f1 cmp %esi,%ecx + 6dd: 74 3a je 719 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 6df: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 6e1: 5b pop %ebx + freep = p; + 6e2: 89 15 64 0b 00 00 mov %edx,0xb64 +} + 6e8: 5e pop %esi + 6e9: 5f pop %edi + 6ea: 5d pop %ebp + 6eb: c3 ret + 6ec: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 6f0: 39 c2 cmp %eax,%edx + 6f2: 72 c4 jb 6b8 + 6f4: 39 c1 cmp %eax,%ecx + 6f6: 73 c0 jae 6b8 + if (bp + bp->s.size == p->s.ptr) { + 6f8: 8b 73 fc mov -0x4(%ebx),%esi + 6fb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 6fe: 39 f8 cmp %edi,%eax + 700: 75 d0 jne 6d2 + bp->s.size += p->s.ptr->s.size; + 702: 03 70 04 add 0x4(%eax),%esi + 705: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 708: 8b 02 mov (%edx),%eax + 70a: 8b 00 mov (%eax),%eax + 70c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 70f: 8b 42 04 mov 0x4(%edx),%eax + 712: 8d 34 c2 lea (%edx,%eax,8),%esi + 715: 39 f1 cmp %esi,%ecx + 717: 75 c6 jne 6df + p->s.size += bp->s.size; + 719: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 71c: 89 15 64 0b 00 00 mov %edx,0xb64 + p->s.size += bp->s.size; + 722: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 725: 8b 4b f8 mov -0x8(%ebx),%ecx + 728: 89 0a mov %ecx,(%edx) +} + 72a: 5b pop %ebx + 72b: 5e pop %esi + 72c: 5f pop %edi + 72d: 5d pop %ebp + 72e: c3 ret + 72f: 90 nop + +00000730 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 730: 55 push %ebp + 731: 89 e5 mov %esp,%ebp + 733: 57 push %edi + 734: 56 push %esi + 735: 53 push %ebx + 736: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 739: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 73c: 8b 3d 64 0b 00 00 mov 0xb64,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 742: 8d 70 07 lea 0x7(%eax),%esi + 745: c1 ee 03 shr $0x3,%esi + 748: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 74b: 85 ff test %edi,%edi + 74d: 0f 84 9d 00 00 00 je 7f0 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 753: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 755: 8b 4a 04 mov 0x4(%edx),%ecx + 758: 39 f1 cmp %esi,%ecx + 75a: 73 6a jae 7c6 + 75c: bb 00 10 00 00 mov $0x1000,%ebx + 761: 39 de cmp %ebx,%esi + 763: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 766: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 76d: 89 45 e4 mov %eax,-0x1c(%ebp) + 770: eb 17 jmp 789 + 772: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 778: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 77a: 8b 48 04 mov 0x4(%eax),%ecx + 77d: 39 f1 cmp %esi,%ecx + 77f: 73 4f jae 7d0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 781: 8b 3d 64 0b 00 00 mov 0xb64,%edi + 787: 89 c2 mov %eax,%edx + 789: 39 d7 cmp %edx,%edi + 78b: 75 eb jne 778 + p = sbrk(nu * sizeof(Header)); + 78d: 83 ec 0c sub $0xc,%esp + 790: ff 75 e4 push -0x1c(%ebp) + 793: e8 4b fc ff ff call 3e3 + if (p == (char*)-1) { + 798: 83 c4 10 add $0x10,%esp + 79b: 83 f8 ff cmp $0xffffffff,%eax + 79e: 74 1c je 7bc + hp->s.size = nu; + 7a0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 7a3: 83 ec 0c sub $0xc,%esp + 7a6: 83 c0 08 add $0x8,%eax + 7a9: 50 push %eax + 7aa: e8 f1 fe ff ff call 6a0 + return freep; + 7af: 8b 15 64 0b 00 00 mov 0xb64,%edx + if ((p = morecore(nunits)) == 0) { + 7b5: 83 c4 10 add $0x10,%esp + 7b8: 85 d2 test %edx,%edx + 7ba: 75 bc jne 778 + return 0; + } + } + } +} + 7bc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 7bf: 31 c0 xor %eax,%eax +} + 7c1: 5b pop %ebx + 7c2: 5e pop %esi + 7c3: 5f pop %edi + 7c4: 5d pop %ebp + 7c5: c3 ret + if (p->s.size >= nunits) { + 7c6: 89 d0 mov %edx,%eax + 7c8: 89 fa mov %edi,%edx + 7ca: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 7d0: 39 ce cmp %ecx,%esi + 7d2: 74 4c je 820 + p->s.size -= nunits; + 7d4: 29 f1 sub %esi,%ecx + 7d6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 7d9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 7dc: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 7df: 89 15 64 0b 00 00 mov %edx,0xb64 +} + 7e5: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 7e8: 83 c0 08 add $0x8,%eax +} + 7eb: 5b pop %ebx + 7ec: 5e pop %esi + 7ed: 5f pop %edi + 7ee: 5d pop %ebp + 7ef: c3 ret + base.s.ptr = freep = prevp = &base; + 7f0: c7 05 64 0b 00 00 68 movl $0xb68,0xb64 + 7f7: 0b 00 00 + base.s.size = 0; + 7fa: bf 68 0b 00 00 mov $0xb68,%edi + base.s.ptr = freep = prevp = &base; + 7ff: c7 05 68 0b 00 00 68 movl $0xb68,0xb68 + 806: 0b 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 809: 89 fa mov %edi,%edx + base.s.size = 0; + 80b: c7 05 6c 0b 00 00 00 movl $0x0,0xb6c + 812: 00 00 00 + if (p->s.size >= nunits) { + 815: e9 42 ff ff ff jmp 75c + 81a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 820: 8b 08 mov (%eax),%ecx + 822: 89 0a mov %ecx,(%edx) + 824: eb b9 jmp 7df diff --git a/stressfs.c b/stressfs.c new file mode 100644 index 0000000..87f10c1 --- /dev/null +++ b/stressfs.c @@ -0,0 +1,51 @@ +// Demonstrate that moving the "acquire" in iderw after the loop that +// appends to the idequeue results in a race. + +// For this to work, you should also add a spin within iderw's +// idequeue traversal loop. Adding the following demonstrated a panic +// after about 5 runs of stressfs in QEMU on a 2.1GHz CPU: +// for (i = 0; i < 40000; i++) +// asm volatile(""); + +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fs.h" +#include "fcntl.h" + +int main(int argc, char *argv[]) { + int fd, i; + char path[] = "stressfs0"; + char data[512]; + + printf(1, "stressfs starting\n"); + memset(data, 'a', sizeof(data)); + + for (i = 0; i < 4; i++) { + if (fork() > 0) { + break; + } + } + + printf(1, "write %d\n", i); + + path[8] += i; + fd = open(path, O_CREATE | O_RDWR); + for (i = 0; i < 20; i++) { +// printf(fd, "%d\n", i); + write(fd, data, sizeof(data)); + } + close(fd); + + printf(1, "read\n"); + + fd = open(path, O_RDONLY); + for (i = 0; i < 20; i++) { + read(fd, data, sizeof(data)); + } + close(fd); + + wait(); + + exit(); +} diff --git a/stressfs.d b/stressfs.d new file mode 100644 index 0000000..7d5de54 --- /dev/null +++ b/stressfs.d @@ -0,0 +1,2 @@ +stressfs.o: stressfs.c /usr/include/stdc-predef.h types.h stat.h user.h \ + fs.h fcntl.h diff --git a/stressfs.o b/stressfs.o new file mode 100644 index 0000000..7aeaa35 Binary files /dev/null and b/stressfs.o differ diff --git a/stressfs.sym b/stressfs.sym new file mode 100644 index 0000000..793fd80 --- /dev/null +++ b/stressfs.sym @@ -0,0 +1,48 @@ +00000000 stressfs.c +00000000 ulib.c +00000000 printf.c +00000450 printint +000008ac digits.0 +00000000 umalloc.c +00000b64 freep +00000b68 base +00000140 strcpy +00000500 printf +0000043b greeting +00000360 memmove +0000040b mknod +00000260 gets +000003db getpid +00000730 malloc +000003eb sleep +000003a3 pipe +00000433 getch +00000403 write +000003c3 fstat +000003b3 kill +000003cb chdir +000003bb exec +0000039b wait +000003ab read +00000413 unlink +0000038b fork +000003e3 sbrk +000003f3 uptime +00000b64 __bss_start +00000200 memset +00000000 main +00000170 strcmp +00000443 shutdown +000003d3 dup +000002d0 stat +00000b64 _edata +00000b70 _end +0000041b link +00000393 exit +00000320 atoi +000001d0 strlen +000003fb open +00000220 strchr +00000423 mkdir +0000042b close +000006a0 free diff --git a/string.c b/string.c new file mode 100644 index 0000000..ffdf897 --- /dev/null +++ b/string.c @@ -0,0 +1,103 @@ +#include "types.h" +#include "x86.h" + +void* memset(void *dst, int c, uint n) { + if ((int)dst % 4 == 0 && n % 4 == 0) { + c &= 0xFF; + stosl(dst, (c << 24) | (c << 16) | (c << 8) | c, n / 4); + } + else { + stosb(dst, c, n); + } + return dst; +} + +int memcmp(const void *v1, const void *v2, uint n) { + const uchar *s1, *s2; + + s1 = v1; + s2 = v2; + while (n-- > 0) { + if (*s1 != *s2) { + return *s1 - *s2; + } + s1++, s2++; + } + + return 0; +} + +void* memmove(void *dst, const void *src, uint n) { + const char *s; + char *d; + + s = src; + d = dst; + if (s < d && s + n > d) { + s += n; + d += n; + while (n-- > 0) { + *--d = *--s; + } + } + else { + while (n-- > 0) { + *d++ = *s++; + } + } + + return dst; +} + +// memcpy exists to placate GCC. Use memmove. +void* memcpy(void *dst, const void *src, uint n) { + return memmove(dst, src, n); +} + +int strncmp(const char *p, const char *q, uint n) { + while (n > 0 && *p && *p == *q) { + n--, p++, q++; + } + if (n == 0) { + return 0; + } + return (uchar) * p - (uchar) * q; +} + +char* strncpy(char *s, const char *t, int n) { + char *os; + + os = s; + while (n-- > 0 && (*s++ = *t++) != 0) { + ; + } + while (n-- > 0) { + *s++ = 0; + } + return os; +} + +// Like strncpy but guaranteed to NUL-terminate. +char* safestrcpy(char *s, const char *t, int n) { + char *os; + + os = s; + if (n <= 0) { + return os; + } + while (--n > 0 && (*s++ = *t++) != 0) { + ; + } + *s = 0; + return os; +} + +int strlen(const char *s) { + int n; + + for (n = 0; s[n]; n++) { + ; + } + return n; +} + diff --git a/string.d b/string.d new file mode 100644 index 0000000..68931ed --- /dev/null +++ b/string.d @@ -0,0 +1 @@ +string.o: string.c /usr/include/stdc-predef.h types.h x86.h diff --git a/string.o b/string.o new file mode 100644 index 0000000..4431e96 Binary files /dev/null and b/string.o differ diff --git a/swtch.S b/swtch.S new file mode 100644 index 0000000..c395b87 --- /dev/null +++ b/swtch.S @@ -0,0 +1,29 @@ +# Context switch +# +# void swtch(struct context **old, struct context *new); +# +# Save the current registers on the stack, creating +# a struct context, and save its address in *old. +# Switch stacks to new and pop previously-saved registers. + +.globl swtch +swtch: + movl 4(%esp), %eax + movl 8(%esp), %edx + + # Save old callee-saved registers + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + + # Switch stacks + movl %esp, (%eax) + movl %edx, %esp + + # Load new callee-saved registers + popl %edi + popl %esi + popl %ebx + popl %ebp + ret diff --git a/swtch.o b/swtch.o new file mode 100644 index 0000000..29c6b7d Binary files /dev/null and b/swtch.o differ diff --git a/syscall.c b/syscall.c new file mode 100644 index 0000000..5086c9a --- /dev/null +++ b/syscall.c @@ -0,0 +1,95 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "x86.h" +#include "syscall.h" +#include "syscalltable.h" + +// User code makes a system call with INT T_SYSCALL. +// System call number in %eax. +// Arguments on the stack, from the user call to the C +// library system call function. The saved user %esp points +// to a saved program counter, and then the first argument. + +// Fetch the int at addr from the current process. +int fetchint(uint addr, int *ip) { + struct proc *curproc = myproc(); + + if (addr >= curproc->sz || addr + 4 > curproc->sz) { + return -1; + } + *ip = *(int*)(addr); + return 0; +} + +// Fetch the nul-terminated string at addr from the current process. +// Doesn't actually copy the string - just sets *pp to point at it. +// Returns length of string, not including nul. +int fetchstr(uint addr, char **pp) { + char *s, *ep; + struct proc *curproc = myproc(); + + if (addr >= curproc->sz) { + return -1; + } + *pp = (char*)addr; + ep = (char*)curproc->sz; + for (s = *pp; s < ep; s++) { + if (*s == 0) { + return s - *pp; + } + } + return -1; +} + +// Fetch the nth 32-bit system call argument. +int argint(int n, int *ip) { + return fetchint((myproc()->tf->esp) + 4 + 4 * n, ip); +} + +// Fetch the nth word-sized system call argument as a pointer +// to a block of memory of size bytes. Check that the pointer +// lies within the process address space. +int argptr(int n, char **pp, int size) { + int i; + struct proc *curproc = myproc(); + + if (argint(n, &i) < 0) { + return -1; + } + if (size < 0 || (uint)i >= curproc->sz || (uint)i + size > curproc->sz) { + return -1; + } + *pp = (char*)i; + return 0; +} + +// Fetch the nth word-sized system call argument as a string pointer. +// Check that the pointer is valid and the string is nul-terminated. +// (There is no shared writable memory, so the string can't change +// between this check and being used by the kernel.) +int argstr(int n, char **pp) { + int addr; + if (argint(n, &addr) < 0) { + return -1; + } + return fetchstr(addr, pp); +} + +void syscall(void) { + int num; + struct proc *curproc = myproc(); + + num = curproc->tf->eax; + if (num > 0 && num < NELEM(syscalls) && syscalls[num]) { + curproc->tf->eax = syscalls[num](); + } + else { + cprintf("%d %s: unknown sys call %d\n", + curproc->pid, curproc->name, num); + curproc->tf->eax = -1; + } +} diff --git a/syscall.d b/syscall.d new file mode 100644 index 0000000..07012da --- /dev/null +++ b/syscall.d @@ -0,0 +1,2 @@ +syscall.o: syscall.c /usr/include/stdc-predef.h types.h defs.h param.h \ + memlayout.h mmu.h proc.h x86.h syscall.h syscalltable.h diff --git a/syscall.h b/syscall.h new file mode 100644 index 0000000..e4f4d88 --- /dev/null +++ b/syscall.h @@ -0,0 +1,27 @@ +// Generated by gensyscalls.pl. Do not edit. +// To change syscall numbers or add new syscalls, edit gensyscalls.pl + +#define SYS_fork 1 +#define SYS_exit 2 +#define SYS_wait 3 +#define SYS_pipe 4 +#define SYS_read 5 +#define SYS_kill 6 +#define SYS_exec 7 +#define SYS_fstat 8 +#define SYS_chdir 9 +#define SYS_dup 10 +#define SYS_getpid 11 +#define SYS_sbrk 12 +#define SYS_sleep 13 +#define SYS_uptime 14 +#define SYS_open 15 +#define SYS_write 16 +#define SYS_mknod 17 +#define SYS_unlink 18 +#define SYS_link 19 +#define SYS_mkdir 20 +#define SYS_close 21 +#define SYS_getch 22 +#define SYS_greeting 23 +#define SYS_shutdown 24 diff --git a/syscall.o b/syscall.o new file mode 100644 index 0000000..e018436 Binary files /dev/null and b/syscall.o differ diff --git a/syscalltable.h b/syscalltable.h new file mode 100644 index 0000000..bbfbc10 --- /dev/null +++ b/syscalltable.h @@ -0,0 +1,54 @@ +// Generated by gensyscalls.pl. Do not edit. +// To change syscall numbers or add new syscalls, edit gensyscalls.pl + +extern int sys_fork(void); +extern int sys_exit(void); +extern int sys_wait(void); +extern int sys_pipe(void); +extern int sys_read(void); +extern int sys_kill(void); +extern int sys_exec(void); +extern int sys_fstat(void); +extern int sys_chdir(void); +extern int sys_dup(void); +extern int sys_getpid(void); +extern int sys_sbrk(void); +extern int sys_sleep(void); +extern int sys_uptime(void); +extern int sys_open(void); +extern int sys_write(void); +extern int sys_mknod(void); +extern int sys_unlink(void); +extern int sys_link(void); +extern int sys_mkdir(void); +extern int sys_close(void); +extern int sys_getch(void); +extern int sys_greeting(void); +extern int sys_shutdown(void); + +static int(*syscalls[])(void) = { +[SYS_fork] sys_fork, +[SYS_exit] sys_exit, +[SYS_wait] sys_wait, +[SYS_pipe] sys_pipe, +[SYS_read] sys_read, +[SYS_kill] sys_kill, +[SYS_exec] sys_exec, +[SYS_fstat] sys_fstat, +[SYS_chdir] sys_chdir, +[SYS_dup] sys_dup, +[SYS_getpid] sys_getpid, +[SYS_sbrk] sys_sbrk, +[SYS_sleep] sys_sleep, +[SYS_uptime] sys_uptime, +[SYS_open] sys_open, +[SYS_write] sys_write, +[SYS_mknod] sys_mknod, +[SYS_unlink] sys_unlink, +[SYS_link] sys_link, +[SYS_mkdir] sys_mkdir, +[SYS_close] sys_close, +[SYS_getch] sys_getch, +[SYS_greeting] sys_greeting, +[SYS_shutdown] sys_shutdown, +}; diff --git a/sysfile.c b/sysfile.c new file mode 100644 index 0000000..faf89dc --- /dev/null +++ b/sysfile.c @@ -0,0 +1,450 @@ +// +// File-system system calls. +// Mostly argument checking, since we don't trust +// user code, and calls into file.c and fs.c. +// + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "stat.h" +#include "mmu.h" +#include "proc.h" +#include "fs.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "file.h" +#include "fcntl.h" + +// Fetch the nth word-sized system call argument as a file descriptor +// and return both the descriptor and the corresponding struct file. +static int argfd(int n, int *pfd, struct file **pf) { + int fd; + struct file *f; + + if (argint(n, &fd) < 0) { + return -1; + } + if (fd < 0 || fd >= NOFILE || (f = myproc()->ofile[fd]) == 0) { + return -1; + } + if (pfd) { + *pfd = fd; + } + if (pf) { + *pf = f; + } + return 0; +} + +// Allocate a file descriptor for the given file. +// Takes over file reference from caller on success. +static int fdalloc(struct file *f) { + int fd; + struct proc *curproc = myproc(); + + for (fd = 0; fd < NOFILE; fd++) { + if (curproc->ofile[fd] == 0) { + curproc->ofile[fd] = f; + return fd; + } + } + return -1; +} + +int sys_dup(void) { + struct file *f; + int fd; + + if (argfd(0, 0, &f) < 0) { + return -1; + } + if ((fd = fdalloc(f)) < 0) { + return -1; + } + filedup(f); + return fd; +} + +int sys_read(void) { + struct file *f; + int n; + char *p; + + if (argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) { + return -1; + } + return fileread(f, p, n); +} + +int sys_write(void) { + struct file *f; + int n; + char *p; + + if (argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) { + return -1; + } + return filewrite(f, p, n); +} + +int sys_close(void) { + int fd; + struct file *f; + + if (argfd(0, &fd, &f) < 0) { + return -1; + } + myproc()->ofile[fd] = 0; + fileclose(f); + return 0; +} + +int sys_fstat(void) { + struct file *f; + struct stat *st; + + if (argfd(0, 0, &f) < 0 || argptr(1, (void*)&st, sizeof(*st)) < 0) { + return -1; + } + return filestat(f, st); +} + +void cleanupsyslink(struct inode * ip) { + ilock(ip); + ip->nlink--; + iupdate(ip); + iunlockput(ip); + end_op(); +} + +// Create the path new as a link to the same inode as old. +int sys_link(void) { + char name[DIRSIZ], *new, *old; + struct inode *dp, *ip; + + if (argstr(0, &old) < 0 || argstr(1, &new) < 0) { + return -1; + } + + begin_op(); + if ((ip = namei(old)) == 0) { + end_op(); + return -1; + } + + ilock(ip); + if (ip->type == T_DIR) { + iunlockput(ip); + end_op(); + return -1; + } + + ip->nlink++; + iupdate(ip); + iunlock(ip); + + if ((dp = nameiparent(new, name)) == 0) { + cleanupsyslink(ip); + return -1; + } + ilock(dp); + if (dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0) { + iunlockput(dp); + cleanupsyslink(ip); + return -1; + } + iunlockput(dp); + iput(ip); + + end_op(); + + return 0; +} + +// Is the directory dp empty except for "." and ".." ? +static int isdirempty(struct inode *dp) { + int off; + struct dirent de; + + for (off = 2 * sizeof(de); off < dp->size; off += sizeof(de)) { + if (readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { + panic("isdirempty: readi"); + } + if (de.inum != 0) { + return 0; + } + } + return 1; +} + + +int sys_unlink(void) { + struct inode *ip, *dp; + struct dirent de; + char name[DIRSIZ], *path; + uint off; + + if (argstr(0, &path) < 0) { + return -1; + } + + begin_op(); + if ((dp = nameiparent(path, name)) == 0) { + end_op(); + return -1; + } + + ilock(dp); + + // Cannot unlink "." or "..". + if (namecmp(name, ".") == 0 || namecmp(name, "..") == 0) { + iunlockput(dp); + end_op(); + return -1; + } + + if ((ip = dirlookup(dp, name, &off)) == 0) { + iunlockput(dp); + end_op(); + return -1; + } + ilock(ip); + + if (ip->nlink < 1) { + panic("unlink: nlink < 1"); + } + if (ip->type == T_DIR && !isdirempty(ip)) { + iunlockput(ip); + iunlockput(dp); + end_op(); + return -1; + } + + memset(&de, 0, sizeof(de)); + if (writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) { + panic("unlink: writei"); + } + if (ip->type == T_DIR) { + dp->nlink--; + iupdate(dp); + } + iunlockput(dp); + + ip->nlink--; + iupdate(ip); + iunlockput(ip); + + end_op(); + + return 0; +} + +static struct inode* create(char *path, short type, short major, short minor) { + struct inode *ip, *dp; + char name[DIRSIZ]; + + if ((dp = nameiparent(path, name)) == 0) { + return 0; + } + ilock(dp); + + if ((ip = dirlookup(dp, name, 0)) != 0) { + iunlockput(dp); + ilock(ip); + if (type == T_FILE && ip->type == T_FILE) { + return ip; + } + iunlockput(ip); + return 0; + } + + if ((ip = ialloc(dp->dev, type)) == 0) { + panic("create: ialloc"); + } + + ilock(ip); + ip->major = major; + ip->minor = minor; + ip->nlink = 1; + iupdate(ip); + + if (type == T_DIR) { // Create . and .. entries. + dp->nlink++; // for ".." + iupdate(dp); + // No ip->nlink++ for ".": avoid cyclic ref count. + if (dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0) { + panic("create dots"); + } + } + + if (dirlink(dp, name, ip->inum) < 0) { + panic("create: dirlink"); + } + + iunlockput(dp); + + return ip; +} + +int sys_open(void) { + char *path; + int fd, omode; + struct file *f; + struct inode *ip; + + if (argstr(0, &path) < 0 || argint(1, &omode) < 0) { + return -1; + } + + begin_op(); + + if (omode & O_CREATE) { + ip = create(path, T_FILE, 0, 0); + if (ip == 0) { + end_op(); + return -1; + } + } + else { + if ((ip = namei(path)) == 0) { + end_op(); + return -1; + } + ilock(ip); + if (ip->type == T_DIR && omode != O_RDONLY) { + iunlockput(ip); + end_op(); + return -1; + } + } + + if ((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0) { + if (f) { + fileclose(f); + } + iunlockput(ip); + end_op(); + return -1; + } + iunlock(ip); + end_op(); + + f->type = FD_INODE; + f->ip = ip; + f->off = 0; + f->readable = !(omode & O_WRONLY); + f->writable = (omode & O_WRONLY) || (omode & O_RDWR); + return fd; +} + +int sys_mkdir(void) { + char *path; + struct inode *ip; + + begin_op(); + if (argstr(0, &path) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0) { + end_op(); + return -1; + } + iunlockput(ip); + end_op(); + return 0; +} + +int sys_mknod(void) { + struct inode *ip; + char *path; + int major, minor; + + begin_op(); + if ((argstr(0, &path)) < 0 || + argint(1, &major) < 0 || + argint(2, &minor) < 0 || + (ip = create(path, T_DEV, major, minor)) == 0) { + end_op(); + return -1; + } + iunlockput(ip); + end_op(); + return 0; +} + +int sys_chdir(void) { + char *path; + struct inode *ip; + struct proc *curproc = myproc(); + + begin_op(); + if (argstr(0, &path) < 0 || (ip = namei(path)) == 0) { + end_op(); + return -1; + } + ilock(ip); + if (ip->type != T_DIR) { + iunlockput(ip); + end_op(); + return -1; + } + iunlock(ip); + iput(curproc->cwd); + end_op(); + curproc->cwd = ip; + return 0; +} + +int sys_exec(void) { + char *path, *argv[MAXARG]; + int i; + uint uargv, uarg; + + if (argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0) { + return -1; + } + memset(argv, 0, sizeof(argv)); + for (i = 0;; i++) { + if (i >= NELEM(argv)) { + return -1; + } + if (fetchint(uargv + 4 * i, (int*)&uarg) < 0) { + return -1; + } + if (uarg == 0) { + argv[i] = 0; + break; + } + if (fetchstr(uarg, &argv[i]) < 0) { + return -1; + } + } + return exec(path, argv); +} + +int sys_pipe(void) { + int *fd; + struct file *rf, *wf; + int fd0, fd1; + + if (argptr(0, (void*)&fd, 2 * sizeof(fd[0])) < 0) { + return -1; + } + if (pipealloc(&rf, &wf) < 0) { + return -1; + } + fd0 = -1; + if ((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0) { + if (fd0 >= 0) { + myproc()->ofile[fd0] = 0; + } + fileclose(rf); + fileclose(wf); + return -1; + } + fd[0] = fd0; + fd[1] = fd1; + return 0; +} + +int sys_getch(void) { + return consoleget(); +} \ No newline at end of file diff --git a/sysfile.d b/sysfile.d new file mode 100644 index 0000000..74f1a20 --- /dev/null +++ b/sysfile.d @@ -0,0 +1,2 @@ +sysfile.o: sysfile.c /usr/include/stdc-predef.h types.h defs.h param.h \ + stat.h mmu.h proc.h fs.h spinlock.h sleeplock.h file.h fcntl.h diff --git a/sysfile.o b/sysfile.o new file mode 100644 index 0000000..a9385a1 Binary files /dev/null and b/sysfile.o differ diff --git a/sysproc.c b/sysproc.c new file mode 100644 index 0000000..dc6d039 --- /dev/null +++ b/sysproc.c @@ -0,0 +1,122 @@ +#include "types.h" +#include "x86.h" +#include "defs.h" +#include "date.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" + +int sys_fork(void) +{ + return fork(); +} + +int sys_exit(void) +{ + exit(); + return 0; // not reached +} + +int sys_wait(void) +{ + return wait(); +} + +int sys_kill(void) +{ + int pid; + + if (argint(0, &pid) < 0) + { + return -1; + } + return kill(pid); +} + +int sys_getpid(void) +{ + return myproc()->pid; +} + +int sys_sbrk(void) +{ + int addr; + int n; + + if (argint(0, &n) < 0) + { + return -1; + } + addr = myproc()->sz; + if (growproc(n) < 0) + { + return -1; + } + return addr; +} + +int sys_sleep(void) +{ + int n; + uint ticks0; + + if (argint(0, &n) < 0) + { + return -1; + } + acquire(&tickslock); + ticks0 = ticks; + while (ticks - ticks0 < n) + { + if (myproc()->killed) + { + release(&tickslock); + return -1; + } + sleep(&ticks, &tickslock); + } + release(&tickslock); + return 0; +} + +// return how many clock tick interrupts have occurred +// since start. +int sys_uptime(void) +{ + uint xticks; + + acquire(&tickslock); + xticks = ticks; + release(&tickslock); + return xticks; +} + +int sys_greeting(void) +{ + cprintf("Hello again\n"); + return 0; +} + +int sys_shutdown(void) +{ + int restart; + if (argint(0, &restart) < 0) + { + return -1; + } + + if (restart == 1) + { + unsigned char good = 0x02; + while (good & 0x02) { + good = inb(0x64); + } + outb(0x64, 0xFE); + } + else + { + outw(0x604, 0x2000); + } + return 0; +} \ No newline at end of file diff --git a/sysproc.d b/sysproc.d new file mode 100644 index 0000000..2f26f0c --- /dev/null +++ b/sysproc.d @@ -0,0 +1,2 @@ +sysproc.o: sysproc.c /usr/include/stdc-predef.h types.h x86.h defs.h \ + date.h param.h memlayout.h mmu.h proc.h diff --git a/sysproc.o b/sysproc.o new file mode 100644 index 0000000..8b5cda2 Binary files /dev/null and b/sysproc.o differ diff --git a/trap.c b/trap.c new file mode 100644 index 0000000..fe81ba6 --- /dev/null +++ b/trap.c @@ -0,0 +1,111 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "x86.h" +#include "traps.h" +#include "spinlock.h" + +// Interrupt descriptor table (shared by all CPUs). +struct gatedesc idt[256]; +extern uint vectors[]; // in vectors.S: array of 256 entry pointers +struct spinlock tickslock; +uint ticks; + +void tvinit(void) { + int i; + + for (i = 0; i < 256; i++) { + SETGATE(idt[i], 0, SEG_KCODE << 3, vectors[i], 0); + } + SETGATE(idt[T_SYSCALL], 1, SEG_KCODE << 3, vectors[T_SYSCALL], DPL_USER); + + initlock(&tickslock, "time"); +} + +void idtinit(void) { + lidt(idt, sizeof(idt)); +} + +void trap(struct trapframe *tf) { + if (tf->trapno == T_SYSCALL) { + if (myproc()->killed) { + exit(); + } + myproc()->tf = tf; + syscall(); + if (myproc()->killed) { + exit(); + } + return; + } + + switch (tf->trapno) { + case T_IRQ0 + IRQ_TIMER: + if (cpuid() == 0) { + acquire(&tickslock); + ticks++; + wakeup(&ticks); + release(&tickslock); + } + lapiceoi(); + break; + case T_IRQ0 + IRQ_IDE: + ideintr(); + lapiceoi(); + break; + case T_IRQ0 + IRQ_IDE + 1: + // Bochs generates spurious IDE1 interrupts. + break; + case T_IRQ0 + IRQ_KBD: + kbdintr(); + lapiceoi(); + break; + case T_IRQ0 + IRQ_COM1: + uartintr(); + lapiceoi(); + break; + case T_IRQ0 + 7: + case T_IRQ0 + IRQ_SPURIOUS: + cprintf("cpu%d: spurious interrupt at %x:%x\n", + cpuid(), tf->cs, tf->eip); + lapiceoi(); + break; + + + default: + if (myproc() == 0 || (tf->cs & 3) == 0) { + // In kernel, it must be our mistake. + cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n", + tf->trapno, cpuid(), tf->eip, rcr2()); + panic("trap"); + } + // In user space, assume process misbehaved. + cprintf("pid %d %s: trap %d err %d on cpu %d " + "eip 0x%x addr 0x%x--kill proc\n", + myproc()->pid, myproc()->name, tf->trapno, + tf->err, cpuid(), tf->eip, rcr2()); + myproc()->killed = 1; + } + + // Force process exit if it has been killed and is in user space. + // (If it is still executing in the kernel, let it keep running + // until it gets to the regular system call return.) + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { + exit(); + } + + // Force process to give up CPU on clock tick. + // If interrupts were on while locks held, would need to check nlock. + if (myproc() && myproc()->state == RUNNING && + tf->trapno == T_IRQ0 + IRQ_TIMER) { + yield(); + } + + // Check if the process has been killed since we yielded + if (myproc() && myproc()->killed && (tf->cs & 3) == DPL_USER) { + exit(); + } +} diff --git a/trap.d b/trap.d new file mode 100644 index 0000000..c48ab89 --- /dev/null +++ b/trap.d @@ -0,0 +1,2 @@ +trap.o: trap.c /usr/include/stdc-predef.h types.h defs.h param.h \ + memlayout.h mmu.h proc.h x86.h traps.h spinlock.h diff --git a/trap.o b/trap.o new file mode 100644 index 0000000..c76deb1 Binary files /dev/null and b/trap.o differ diff --git a/trapasm.S b/trapasm.S new file mode 100644 index 0000000..d70262e --- /dev/null +++ b/trapasm.S @@ -0,0 +1,32 @@ +#include "mmu.h" + + # vectors.S sends all traps here. +.globl alltraps +alltraps: + # Build trap frame. + pushl %ds + pushl %es + pushl %fs + pushl %gs + pushal + + # Set up data segments. + movw $(SEG_KDATA<<3), %ax + movw %ax, %ds + movw %ax, %es + + # Call trap(tf), where tf=%esp + pushl %esp + call trap + addl $4, %esp + + # Return falls through to trapret... +.globl trapret +trapret: + popal + popl %gs + popl %fs + popl %es + popl %ds + addl $0x8, %esp # trapno and errcode + iret diff --git a/trapasm.o b/trapasm.o new file mode 100644 index 0000000..b5ce65b Binary files /dev/null and b/trapasm.o differ diff --git a/traps.h b/traps.h new file mode 100644 index 0000000..0bd1fd8 --- /dev/null +++ b/traps.h @@ -0,0 +1,38 @@ +// x86 trap and interrupt constants. + +// Processor-defined: +#define T_DIVIDE 0 // divide error +#define T_DEBUG 1 // debug exception +#define T_NMI 2 // non-maskable interrupt +#define T_BRKPT 3 // breakpoint +#define T_OFLOW 4 // overflow +#define T_BOUND 5 // bounds check +#define T_ILLOP 6 // illegal opcode +#define T_DEVICE 7 // device not available +#define T_DBLFLT 8 // double fault +// #define T_COPROC 9 // reserved (not used since 486) +#define T_TSS 10 // invalid task switch segment +#define T_SEGNP 11 // segment not present +#define T_STACK 12 // stack exception +#define T_GPFLT 13 // general protection fault +#define T_PGFLT 14 // page fault +// #define T_RES 15 // reserved +#define T_FPERR 16 // floating point error +#define T_ALIGN 17 // aligment check +#define T_MCHK 18 // machine check +#define T_SIMDERR 19 // SIMD floating point error + +// These are arbitrarily chosen, but with care not to overlap +// processor defined exceptions or interrupt vectors. +#define T_SYSCALL 64 // system call +#define T_DEFAULT 500 // catchall + +#define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ + +#define IRQ_TIMER 0 +#define IRQ_KBD 1 +#define IRQ_COM1 4 +#define IRQ_IDE 14 +#define IRQ_ERROR 19 +#define IRQ_SPURIOUS 31 + diff --git a/types.h b/types.h new file mode 100644 index 0000000..e4adf64 --- /dev/null +++ b/types.h @@ -0,0 +1,4 @@ +typedef unsigned int uint; +typedef unsigned short ushort; +typedef unsigned char uchar; +typedef uint pde_t; diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..fba91b1 --- /dev/null +++ b/uart.c @@ -0,0 +1,75 @@ +// Intel 8250 serial port (UART). + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "traps.h" +#include "spinlock.h" +#include "sleeplock.h" +#include "fs.h" +#include "file.h" +#include "mmu.h" +#include "proc.h" +#include "x86.h" + +#define COM1 0x3f8 + +static int uart; // is there a uart? + +void uartinit(void) { + char *p; + + // Turn off the FIFO + outb(COM1 + 2, 0); + + // 9600 baud, 8 data bits, 1 stop bit, parity off. + outb(COM1 + 3, 0x80); // Unlock divisor + outb(COM1 + 0, 115200 / 9600); + outb(COM1 + 1, 0); + outb(COM1 + 3, 0x03); // Lock divisor, 8 data bits. + outb(COM1 + 4, 0); + outb(COM1 + 1, 0x01); // Enable receive interrupts. + + // If status is 0xFF, no serial port. + if (inb(COM1 + 5) == 0xFF) { + return; + } + uart = 1; + + // Acknowledge pre-existing interrupt conditions; + // enable interrupts. + inb(COM1 + 2); + inb(COM1 + 0); + ioapicenable(IRQ_COM1, 0); + + // Announce that we're here. + for (p = "xv6...\n"; *p; p++) { + uartputc(*p); + } +} + +void uartputc(int c) { + int i; + + if (!uart) { + return; + } + for (i = 0; i < 128 && !(inb(COM1 + 5) & 0x20); i++) { + microdelay(10); + } + outb(COM1 + 0, c); +} + +static int uartgetc(void) { + if (!uart) { + return -1; + } + if (!(inb(COM1 + 5) & 0x01)) { + return -1; + } + return inb(COM1 + 0); +} + +void uartintr(void) { + consoleintr(uartgetc); +} diff --git a/uart.d b/uart.d new file mode 100644 index 0000000..d156629 --- /dev/null +++ b/uart.d @@ -0,0 +1,2 @@ +uart.o: uart.c /usr/include/stdc-predef.h types.h defs.h param.h traps.h \ + spinlock.h sleeplock.h fs.h file.h mmu.h proc.h x86.h diff --git a/uart.o b/uart.o new file mode 100644 index 0000000..27f864c Binary files /dev/null and b/uart.o differ diff --git a/ulib.c b/ulib.c new file mode 100644 index 0000000..7d10b08 --- /dev/null +++ b/ulib.c @@ -0,0 +1,98 @@ +#include "types.h" +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + ; + } + return os; +} + +int strcmp(const char *p, const char *q) { + while (*p && *p == *q) { + p++, q++; + } + return (uchar) * p - (uchar) * q; +} + +uint strlen(const char *s) { + int n; + + for (n = 0; s[n]; n++) { + ; + } + return n; +} + +void* memset(void *dst, int c, uint n) { + stosb(dst, c, n); + return dst; +} + +char* strchr(const char *s, char c) { + for (; *s; s++) { + if (*s == c) { + return (char*)s; + } + } + return 0; +} + +char* gets(char *buf, int max) { + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + if (cc < 1) { + break; + } + buf[i++] = c; + if (c == '\n' || c == '\r') { + break; + } + } + buf[i] = '\0'; + return buf; +} + +int stat(const char *n, struct stat *st) { + int fd; + int r; + + fd = open(n, O_RDONLY); + if (fd < 0) { + return -1; + } + r = fstat(fd, st); + close(fd); + return r; +} + +int atoi(const char *s) { + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + n = n * 10 + *s++ - '0'; + } + return n; +} + +void* memmove(void *vdst, const void *vsrc, int n) { + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + *dst++ = *src++; + } + return vdst; +} diff --git a/ulib.d b/ulib.d new file mode 100644 index 0000000..61f575e --- /dev/null +++ b/ulib.d @@ -0,0 +1,2 @@ +ulib.o: ulib.c /usr/include/stdc-predef.h types.h stat.h fcntl.h user.h \ + x86.h diff --git a/ulib.o b/ulib.o new file mode 100644 index 0000000..2a6f7b7 Binary files /dev/null and b/ulib.o differ diff --git a/umalloc.c b/umalloc.c new file mode 100644 index 0000000..5ee8a47 --- /dev/null +++ b/umalloc.c @@ -0,0 +1,95 @@ +#include "types.h" +#include "stat.h" +#include "user.h" +#include "param.h" + +// Memory allocator by Kernighan and Ritchie, +// The C programming Language, 2nd ed. Section 8.7. + +typedef long Align; + +union header { + struct { + union header *ptr; + uint size; + } s; + Align x; +}; + +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } + else { + p->s.ptr = bp; + } + freep = p; +} + +static Header* morecore(uint nu) { + char *p; + Header *hp; + + if (nu < 4096) { + nu = 4096; + } + p = sbrk(nu * sizeof(Header)); + if (p == (char*)-1) { + return 0; + } + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + if ((prevp = freep) == 0) { + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + if (p->s.size >= nunits) { + if (p->s.size == nunits) { + prevp->s.ptr = p->s.ptr; + } + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + if ((p = morecore(nunits)) == 0) { + return 0; + } + } + } +} diff --git a/umalloc.d b/umalloc.d new file mode 100644 index 0000000..cc1d152 --- /dev/null +++ b/umalloc.d @@ -0,0 +1,2 @@ +umalloc.o: umalloc.c /usr/include/stdc-predef.h types.h stat.h user.h \ + param.h diff --git a/umalloc.o b/umalloc.o new file mode 100644 index 0000000..2041a13 Binary files /dev/null and b/umalloc.o differ diff --git a/user.h b/user.h new file mode 100644 index 0000000..6de561d --- /dev/null +++ b/user.h @@ -0,0 +1,42 @@ +struct stat; +struct rtcdate; + +// system calls +int fork(void); +int exit(void) __attribute__((noreturn)); +int wait(void); +int pipe(int*); +int write(int, const void*, int); +int read(int, void*, int); +int close(int); +int kill(int); +int exec(char*, char**); +int open(const char*, int); +int mknod(const char*, short, short); +int unlink(const char*); +int fstat(int fd, struct stat*); +int link(const char*, const char*); +int mkdir(const char*); +int chdir(const char*); +int dup(int); +int getpid(void); +char* sbrk(int); +int sleep(int); +int uptime(void); +int getch(void); +int greeting(void); +int shutdown(int restart); + +// ulib.c +int stat(const char*, struct stat*); +char* strcpy(char*, const char*); +void *memmove(void*, const void*, int); +char* strchr(const char*, char c); +int strcmp(const char*, const char*); +void printf(int, const char*, ...); +char* gets(char*, int max); +uint strlen(const char*); +void* memset(void*, int, uint); +void* malloc(uint); +void free(void*); +int atoi(const char*); diff --git a/usertests.asm b/usertests.asm new file mode 100644 index 0000000..3570653 --- /dev/null +++ b/usertests.asm @@ -0,0 +1,6618 @@ + +_usertests: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: +unsigned int rand() { + randstate = randstate * 1664525 + 1013904223; + return randstate; +} + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 51 push %ecx + e: 83 ec 0c sub $0xc,%esp + printf(1, "usertests starting\n"); + 11: 68 56 4d 00 00 push $0x4d56 + 16: 6a 01 push $0x1 + 18: e8 23 3a 00 00 call 3a40 + + if (open("usertests.ran", 0) >= 0) { + 1d: 59 pop %ecx + 1e: 58 pop %eax + 1f: 6a 00 push $0x0 + 21: 68 6a 4d 00 00 push $0x4d6a + 26: e8 10 39 00 00 call 393b + 2b: 83 c4 10 add $0x10,%esp + 2e: 85 c0 test %eax,%eax + 30: 78 13 js 45 + printf(1, "already ran user tests -- rebuild fs.img\n"); + 32: 52 push %edx + 33: 52 push %edx + 34: 68 d4 54 00 00 push $0x54d4 + 39: 6a 01 push $0x1 + 3b: e8 00 3a 00 00 call 3a40 + exit(); + 40: e8 8e 38 00 00 call 38d3 + } + close(open("usertests.ran", O_CREATE)); + 45: 50 push %eax + 46: 50 push %eax + 47: 68 00 02 00 00 push $0x200 + 4c: 68 6a 4d 00 00 push $0x4d6a + 51: e8 e5 38 00 00 call 393b + 56: 89 04 24 mov %eax,(%esp) + 59: e8 0d 39 00 00 call 396b + + argptest(); + 5e: e8 8d 35 00 00 call 35f0 + createdelete(); + 63: e8 b8 11 00 00 call 1220 + linkunlink(); + 68: e8 73 1a 00 00 call 1ae0 + concreate(); + 6d: e8 6e 17 00 00 call 17e0 + fourfiles(); + 72: e8 a9 0f 00 00 call 1020 + sharedfd(); + 77: e8 e4 0d 00 00 call e60 + + bigargtest(); + 7c: e8 2f 32 00 00 call 32b0 + bigwrite(); + 81: e8 7a 23 00 00 call 2400 + bigargtest(); + 86: e8 25 32 00 00 call 32b0 + bsstest(); + 8b: e8 b0 31 00 00 call 3240 + sbrktest(); + 90: e8 ab 2c 00 00 call 2d40 + validatetest(); + 95: e8 f6 30 00 00 call 3190 + + opentest(); + 9a: e8 61 03 00 00 call 400 + writetest(); + 9f: e8 ec 03 00 00 call 490 + writetest1(); + a4: e8 c7 05 00 00 call 670 + createtest(); + a9: e8 92 07 00 00 call 840 + + openiputtest(); + ae: e8 4d 02 00 00 call 300 + exitiputtest(); + b3: e8 48 01 00 00 call 200 + iputtest(); + b8: e8 63 00 00 00 call 120 + + mem(); + bd: e8 ce 0c 00 00 call d90 + pipe1(); + c2: e8 59 09 00 00 call a20 + preempt(); + c7: e8 e4 0a 00 00 call bb0 + exitwait(); + cc: e8 3f 0c 00 00 call d10 + + rmdot(); + d1: e8 1a 27 00 00 call 27f0 + fourteen(); + d6: e8 d5 25 00 00 call 26b0 + bigfile(); + db: e8 00 24 00 00 call 24e0 + subdir(); + e0: e8 3b 1c 00 00 call 1d20 + linktest(); + e5: e8 e6 14 00 00 call 15d0 + unlinkread(); + ea: e8 51 13 00 00 call 1440 + dirfile(); + ef: e8 7c 28 00 00 call 2970 + iref(); + f4: e8 77 2a 00 00 call 2b70 + forktest(); + f9: e8 92 2b 00 00 call 2c90 + bigdir(); // slow + fe: e8 ed 1a 00 00 call 1bf0 + + uio(); + 103: e8 78 34 00 00 call 3580 + + exectest(); + 108: e8 c3 08 00 00 call 9d0 + + exit(); + 10d: e8 c1 37 00 00 call 38d3 + 112: 66 90 xchg %ax,%ax + 114: 66 90 xchg %ax,%ax + 116: 66 90 xchg %ax,%ax + 118: 66 90 xchg %ax,%ax + 11a: 66 90 xchg %ax,%ax + 11c: 66 90 xchg %ax,%ax + 11e: 66 90 xchg %ax,%ax + +00000120 : +void iputtest(void) { + 120: 55 push %ebp + 121: 89 e5 mov %esp,%ebp + 123: 83 ec 10 sub $0x10,%esp + printf(stdout, "iput test\n"); + 126: 68 fc 3d 00 00 push $0x3dfc + 12b: ff 35 58 5e 00 00 push 0x5e58 + 131: e8 0a 39 00 00 call 3a40 + if (mkdir("iputdir") < 0) { + 136: c7 04 24 8f 3d 00 00 movl $0x3d8f,(%esp) + 13d: e8 21 38 00 00 call 3963 + 142: 83 c4 10 add $0x10,%esp + 145: 85 c0 test %eax,%eax + 147: 78 58 js 1a1 + if (chdir("iputdir") < 0) { + 149: 83 ec 0c sub $0xc,%esp + 14c: 68 8f 3d 00 00 push $0x3d8f + 151: e8 b5 37 00 00 call 390b + 156: 83 c4 10 add $0x10,%esp + 159: 85 c0 test %eax,%eax + 15b: 0f 88 85 00 00 00 js 1e6 + if (unlink("../iputdir") < 0) { + 161: 83 ec 0c sub $0xc,%esp + 164: 68 8c 3d 00 00 push $0x3d8c + 169: e8 e5 37 00 00 call 3953 + 16e: 83 c4 10 add $0x10,%esp + 171: 85 c0 test %eax,%eax + 173: 78 5a js 1cf + if (chdir("/") < 0) { + 175: 83 ec 0c sub $0xc,%esp + 178: 68 b1 3d 00 00 push $0x3db1 + 17d: e8 89 37 00 00 call 390b + 182: 83 c4 10 add $0x10,%esp + 185: 85 c0 test %eax,%eax + 187: 78 2f js 1b8 + printf(stdout, "iput test ok\n"); + 189: 83 ec 08 sub $0x8,%esp + 18c: 68 34 3e 00 00 push $0x3e34 + 191: ff 35 58 5e 00 00 push 0x5e58 + 197: e8 a4 38 00 00 call 3a40 +} + 19c: 83 c4 10 add $0x10,%esp + 19f: c9 leave + 1a0: c3 ret + printf(stdout, "mkdir failed\n"); + 1a1: 50 push %eax + 1a2: 50 push %eax + 1a3: 68 68 3d 00 00 push $0x3d68 + 1a8: ff 35 58 5e 00 00 push 0x5e58 + 1ae: e8 8d 38 00 00 call 3a40 + exit(); + 1b3: e8 1b 37 00 00 call 38d3 + printf(stdout, "chdir / failed\n"); + 1b8: 50 push %eax + 1b9: 50 push %eax + 1ba: 68 b3 3d 00 00 push $0x3db3 + 1bf: ff 35 58 5e 00 00 push 0x5e58 + 1c5: e8 76 38 00 00 call 3a40 + exit(); + 1ca: e8 04 37 00 00 call 38d3 + printf(stdout, "unlink ../iputdir failed\n"); + 1cf: 52 push %edx + 1d0: 52 push %edx + 1d1: 68 97 3d 00 00 push $0x3d97 + 1d6: ff 35 58 5e 00 00 push 0x5e58 + 1dc: e8 5f 38 00 00 call 3a40 + exit(); + 1e1: e8 ed 36 00 00 call 38d3 + printf(stdout, "chdir iputdir failed\n"); + 1e6: 51 push %ecx + 1e7: 51 push %ecx + 1e8: 68 76 3d 00 00 push $0x3d76 + 1ed: ff 35 58 5e 00 00 push 0x5e58 + 1f3: e8 48 38 00 00 call 3a40 + exit(); + 1f8: e8 d6 36 00 00 call 38d3 + 1fd: 8d 76 00 lea 0x0(%esi),%esi + +00000200 : +void exitiputtest(void) { + 200: 55 push %ebp + 201: 89 e5 mov %esp,%ebp + 203: 83 ec 10 sub $0x10,%esp + printf(stdout, "exitiput test\n"); + 206: 68 c3 3d 00 00 push $0x3dc3 + 20b: ff 35 58 5e 00 00 push 0x5e58 + 211: e8 2a 38 00 00 call 3a40 + pid = fork(); + 216: e8 b0 36 00 00 call 38cb + if (pid < 0) { + 21b: 83 c4 10 add $0x10,%esp + 21e: 85 c0 test %eax,%eax + 220: 0f 88 8a 00 00 00 js 2b0 + if (pid == 0) { + 226: 75 50 jne 278 + if (mkdir("iputdir") < 0) { + 228: 83 ec 0c sub $0xc,%esp + 22b: 68 8f 3d 00 00 push $0x3d8f + 230: e8 2e 37 00 00 call 3963 + 235: 83 c4 10 add $0x10,%esp + 238: 85 c0 test %eax,%eax + 23a: 0f 88 87 00 00 00 js 2c7 + if (chdir("iputdir") < 0) { + 240: 83 ec 0c sub $0xc,%esp + 243: 68 8f 3d 00 00 push $0x3d8f + 248: e8 be 36 00 00 call 390b + 24d: 83 c4 10 add $0x10,%esp + 250: 85 c0 test %eax,%eax + 252: 0f 88 86 00 00 00 js 2de + if (unlink("../iputdir") < 0) { + 258: 83 ec 0c sub $0xc,%esp + 25b: 68 8c 3d 00 00 push $0x3d8c + 260: e8 ee 36 00 00 call 3953 + 265: 83 c4 10 add $0x10,%esp + 268: 85 c0 test %eax,%eax + 26a: 78 2c js 298 + exit(); + 26c: e8 62 36 00 00 call 38d3 + 271: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + wait(); + 278: e8 5e 36 00 00 call 38db + printf(stdout, "exitiput test ok\n"); + 27d: 83 ec 08 sub $0x8,%esp + 280: 68 e6 3d 00 00 push $0x3de6 + 285: ff 35 58 5e 00 00 push 0x5e58 + 28b: e8 b0 37 00 00 call 3a40 +} + 290: 83 c4 10 add $0x10,%esp + 293: c9 leave + 294: c3 ret + 295: 8d 76 00 lea 0x0(%esi),%esi + printf(stdout, "unlink ../iputdir failed\n"); + 298: 83 ec 08 sub $0x8,%esp + 29b: 68 97 3d 00 00 push $0x3d97 + 2a0: ff 35 58 5e 00 00 push 0x5e58 + 2a6: e8 95 37 00 00 call 3a40 + exit(); + 2ab: e8 23 36 00 00 call 38d3 + printf(stdout, "fork failed\n"); + 2b0: 51 push %ecx + 2b1: 51 push %ecx + 2b2: 68 a9 4c 00 00 push $0x4ca9 + 2b7: ff 35 58 5e 00 00 push 0x5e58 + 2bd: e8 7e 37 00 00 call 3a40 + exit(); + 2c2: e8 0c 36 00 00 call 38d3 + printf(stdout, "mkdir failed\n"); + 2c7: 52 push %edx + 2c8: 52 push %edx + 2c9: 68 68 3d 00 00 push $0x3d68 + 2ce: ff 35 58 5e 00 00 push 0x5e58 + 2d4: e8 67 37 00 00 call 3a40 + exit(); + 2d9: e8 f5 35 00 00 call 38d3 + printf(stdout, "child chdir failed\n"); + 2de: 50 push %eax + 2df: 50 push %eax + 2e0: 68 d2 3d 00 00 push $0x3dd2 + 2e5: ff 35 58 5e 00 00 push 0x5e58 + 2eb: e8 50 37 00 00 call 3a40 + exit(); + 2f0: e8 de 35 00 00 call 38d3 + 2f5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2fc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000300 : +void openiputtest(void) { + 300: 55 push %ebp + 301: 89 e5 mov %esp,%ebp + 303: 83 ec 10 sub $0x10,%esp + printf(stdout, "openiput test\n"); + 306: 68 f8 3d 00 00 push $0x3df8 + 30b: ff 35 58 5e 00 00 push 0x5e58 + 311: e8 2a 37 00 00 call 3a40 + if (mkdir("oidir") < 0) { + 316: c7 04 24 07 3e 00 00 movl $0x3e07,(%esp) + 31d: e8 41 36 00 00 call 3963 + 322: 83 c4 10 add $0x10,%esp + 325: 85 c0 test %eax,%eax + 327: 0f 88 9f 00 00 00 js 3cc + pid = fork(); + 32d: e8 99 35 00 00 call 38cb + if (pid < 0) { + 332: 85 c0 test %eax,%eax + 334: 78 7f js 3b5 + if (pid == 0) { + 336: 75 38 jne 370 + int fd = open("oidir", O_RDWR); + 338: 83 ec 08 sub $0x8,%esp + 33b: 6a 02 push $0x2 + 33d: 68 07 3e 00 00 push $0x3e07 + 342: e8 f4 35 00 00 call 393b + if (fd >= 0) { + 347: 83 c4 10 add $0x10,%esp + 34a: 85 c0 test %eax,%eax + 34c: 78 62 js 3b0 + printf(stdout, "open directory for write succeeded\n"); + 34e: 83 ec 08 sub $0x8,%esp + 351: 68 8c 4d 00 00 push $0x4d8c + 356: ff 35 58 5e 00 00 push 0x5e58 + 35c: e8 df 36 00 00 call 3a40 + exit(); + 361: e8 6d 35 00 00 call 38d3 + 366: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 36d: 8d 76 00 lea 0x0(%esi),%esi + sleep(1); + 370: 83 ec 0c sub $0xc,%esp + 373: 6a 01 push $0x1 + 375: e8 b1 35 00 00 call 392b + if (unlink("oidir") != 0) { + 37a: c7 04 24 07 3e 00 00 movl $0x3e07,(%esp) + 381: e8 cd 35 00 00 call 3953 + 386: 83 c4 10 add $0x10,%esp + 389: 85 c0 test %eax,%eax + 38b: 75 56 jne 3e3 + wait(); + 38d: e8 49 35 00 00 call 38db + printf(stdout, "openiput test ok\n"); + 392: 83 ec 08 sub $0x8,%esp + 395: 68 30 3e 00 00 push $0x3e30 + 39a: ff 35 58 5e 00 00 push 0x5e58 + 3a0: e8 9b 36 00 00 call 3a40 +} + 3a5: 83 c4 10 add $0x10,%esp + 3a8: c9 leave + 3a9: c3 ret + 3aa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + exit(); + 3b0: e8 1e 35 00 00 call 38d3 + printf(stdout, "fork failed\n"); + 3b5: 52 push %edx + 3b6: 52 push %edx + 3b7: 68 a9 4c 00 00 push $0x4ca9 + 3bc: ff 35 58 5e 00 00 push 0x5e58 + 3c2: e8 79 36 00 00 call 3a40 + exit(); + 3c7: e8 07 35 00 00 call 38d3 + printf(stdout, "mkdir oidir failed\n"); + 3cc: 51 push %ecx + 3cd: 51 push %ecx + 3ce: 68 0d 3e 00 00 push $0x3e0d + 3d3: ff 35 58 5e 00 00 push 0x5e58 + 3d9: e8 62 36 00 00 call 3a40 + exit(); + 3de: e8 f0 34 00 00 call 38d3 + printf(stdout, "unlink failed\n"); + 3e3: 50 push %eax + 3e4: 50 push %eax + 3e5: 68 21 3e 00 00 push $0x3e21 + 3ea: ff 35 58 5e 00 00 push 0x5e58 + 3f0: e8 4b 36 00 00 call 3a40 + exit(); + 3f5: e8 d9 34 00 00 call 38d3 + 3fa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +00000400 : +void opentest(void) { + 400: 55 push %ebp + 401: 89 e5 mov %esp,%ebp + 403: 83 ec 10 sub $0x10,%esp + printf(stdout, "open test\n"); + 406: 68 42 3e 00 00 push $0x3e42 + 40b: ff 35 58 5e 00 00 push 0x5e58 + 411: e8 2a 36 00 00 call 3a40 + fd = open("echo", 0); + 416: 58 pop %eax + 417: 5a pop %edx + 418: 6a 00 push $0x0 + 41a: 68 4d 3e 00 00 push $0x3e4d + 41f: e8 17 35 00 00 call 393b + if (fd < 0) { + 424: 83 c4 10 add $0x10,%esp + 427: 85 c0 test %eax,%eax + 429: 78 36 js 461 + close(fd); + 42b: 83 ec 0c sub $0xc,%esp + 42e: 50 push %eax + 42f: e8 37 35 00 00 call 396b + fd = open("doesnotexist", 0); + 434: 5a pop %edx + 435: 59 pop %ecx + 436: 6a 00 push $0x0 + 438: 68 65 3e 00 00 push $0x3e65 + 43d: e8 f9 34 00 00 call 393b + if (fd >= 0) { + 442: 83 c4 10 add $0x10,%esp + 445: 85 c0 test %eax,%eax + 447: 79 2f jns 478 + printf(stdout, "open test ok\n"); + 449: 83 ec 08 sub $0x8,%esp + 44c: 68 90 3e 00 00 push $0x3e90 + 451: ff 35 58 5e 00 00 push 0x5e58 + 457: e8 e4 35 00 00 call 3a40 +} + 45c: 83 c4 10 add $0x10,%esp + 45f: c9 leave + 460: c3 ret + printf(stdout, "open echo failed!\n"); + 461: 50 push %eax + 462: 50 push %eax + 463: 68 52 3e 00 00 push $0x3e52 + 468: ff 35 58 5e 00 00 push 0x5e58 + 46e: e8 cd 35 00 00 call 3a40 + exit(); + 473: e8 5b 34 00 00 call 38d3 + printf(stdout, "open doesnotexist succeeded!\n"); + 478: 50 push %eax + 479: 50 push %eax + 47a: 68 72 3e 00 00 push $0x3e72 + 47f: ff 35 58 5e 00 00 push 0x5e58 + 485: e8 b6 35 00 00 call 3a40 + exit(); + 48a: e8 44 34 00 00 call 38d3 + 48f: 90 nop + +00000490 : +void writetest(void) { + 490: 55 push %ebp + 491: 89 e5 mov %esp,%ebp + 493: 56 push %esi + 494: 53 push %ebx + printf(stdout, "small file test\n"); + 495: 83 ec 08 sub $0x8,%esp + 498: 68 9e 3e 00 00 push $0x3e9e + 49d: ff 35 58 5e 00 00 push 0x5e58 + 4a3: e8 98 35 00 00 call 3a40 + fd = open("small", O_CREATE | O_RDWR); + 4a8: 58 pop %eax + 4a9: 5a pop %edx + 4aa: 68 02 02 00 00 push $0x202 + 4af: 68 af 3e 00 00 push $0x3eaf + 4b4: e8 82 34 00 00 call 393b + if (fd >= 0) { + 4b9: 83 c4 10 add $0x10,%esp + 4bc: 85 c0 test %eax,%eax + 4be: 0f 88 88 01 00 00 js 64c + printf(stdout, "creat small succeeded; ok\n"); + 4c4: 83 ec 08 sub $0x8,%esp + 4c7: 89 c6 mov %eax,%esi + for (i = 0; i < 100; i++) { + 4c9: 31 db xor %ebx,%ebx + printf(stdout, "creat small succeeded; ok\n"); + 4cb: 68 b5 3e 00 00 push $0x3eb5 + 4d0: ff 35 58 5e 00 00 push 0x5e58 + 4d6: e8 65 35 00 00 call 3a40 + 4db: 83 c4 10 add $0x10,%esp + 4de: 66 90 xchg %ax,%ax + if (write(fd, "aaaaaaaaaa", 10) != 10) { + 4e0: 83 ec 04 sub $0x4,%esp + 4e3: 6a 0a push $0xa + 4e5: 68 ec 3e 00 00 push $0x3eec + 4ea: 56 push %esi + 4eb: e8 53 34 00 00 call 3943 + 4f0: 83 c4 10 add $0x10,%esp + 4f3: 83 f8 0a cmp $0xa,%eax + 4f6: 0f 85 d9 00 00 00 jne 5d5 + if (write(fd, "bbbbbbbbbb", 10) != 10) { + 4fc: 83 ec 04 sub $0x4,%esp + 4ff: 6a 0a push $0xa + 501: 68 f7 3e 00 00 push $0x3ef7 + 506: 56 push %esi + 507: e8 37 34 00 00 call 3943 + 50c: 83 c4 10 add $0x10,%esp + 50f: 83 f8 0a cmp $0xa,%eax + 512: 0f 85 d6 00 00 00 jne 5ee + for (i = 0; i < 100; i++) { + 518: 83 c3 01 add $0x1,%ebx + 51b: 83 fb 64 cmp $0x64,%ebx + 51e: 75 c0 jne 4e0 + printf(stdout, "writes ok\n"); + 520: 83 ec 08 sub $0x8,%esp + 523: 68 02 3f 00 00 push $0x3f02 + 528: ff 35 58 5e 00 00 push 0x5e58 + 52e: e8 0d 35 00 00 call 3a40 + close(fd); + 533: 89 34 24 mov %esi,(%esp) + 536: e8 30 34 00 00 call 396b + fd = open("small", O_RDONLY); + 53b: 5b pop %ebx + 53c: 5e pop %esi + 53d: 6a 00 push $0x0 + 53f: 68 af 3e 00 00 push $0x3eaf + 544: e8 f2 33 00 00 call 393b + if (fd >= 0) { + 549: 83 c4 10 add $0x10,%esp + fd = open("small", O_RDONLY); + 54c: 89 c3 mov %eax,%ebx + if (fd >= 0) { + 54e: 85 c0 test %eax,%eax + 550: 0f 88 b1 00 00 00 js 607 + printf(stdout, "open small succeeded ok\n"); + 556: 83 ec 08 sub $0x8,%esp + 559: 68 0d 3f 00 00 push $0x3f0d + 55e: ff 35 58 5e 00 00 push 0x5e58 + 564: e8 d7 34 00 00 call 3a40 + i = read(fd, buf, 2000); + 569: 83 c4 0c add $0xc,%esp + 56c: 68 d0 07 00 00 push $0x7d0 + 571: 68 a0 85 00 00 push $0x85a0 + 576: 53 push %ebx + 577: e8 6f 33 00 00 call 38eb + if (i == 2000) { + 57c: 83 c4 10 add $0x10,%esp + 57f: 3d d0 07 00 00 cmp $0x7d0,%eax + 584: 0f 85 94 00 00 00 jne 61e + printf(stdout, "read succeeded ok\n"); + 58a: 83 ec 08 sub $0x8,%esp + 58d: 68 41 3f 00 00 push $0x3f41 + 592: ff 35 58 5e 00 00 push 0x5e58 + 598: e8 a3 34 00 00 call 3a40 + close(fd); + 59d: 89 1c 24 mov %ebx,(%esp) + 5a0: e8 c6 33 00 00 call 396b + if (unlink("small") < 0) { + 5a5: c7 04 24 af 3e 00 00 movl $0x3eaf,(%esp) + 5ac: e8 a2 33 00 00 call 3953 + 5b1: 83 c4 10 add $0x10,%esp + 5b4: 85 c0 test %eax,%eax + 5b6: 78 7d js 635 + printf(stdout, "small file test ok\n"); + 5b8: 83 ec 08 sub $0x8,%esp + 5bb: 68 69 3f 00 00 push $0x3f69 + 5c0: ff 35 58 5e 00 00 push 0x5e58 + 5c6: e8 75 34 00 00 call 3a40 +} + 5cb: 83 c4 10 add $0x10,%esp + 5ce: 8d 65 f8 lea -0x8(%ebp),%esp + 5d1: 5b pop %ebx + 5d2: 5e pop %esi + 5d3: 5d pop %ebp + 5d4: c3 ret + printf(stdout, "error: write aa %d new file failed\n", i); + 5d5: 83 ec 04 sub $0x4,%esp + 5d8: 53 push %ebx + 5d9: 68 b0 4d 00 00 push $0x4db0 + 5de: ff 35 58 5e 00 00 push 0x5e58 + 5e4: e8 57 34 00 00 call 3a40 + exit(); + 5e9: e8 e5 32 00 00 call 38d3 + printf(stdout, "error: write bb %d new file failed\n", i); + 5ee: 83 ec 04 sub $0x4,%esp + 5f1: 53 push %ebx + 5f2: 68 d4 4d 00 00 push $0x4dd4 + 5f7: ff 35 58 5e 00 00 push 0x5e58 + 5fd: e8 3e 34 00 00 call 3a40 + exit(); + 602: e8 cc 32 00 00 call 38d3 + printf(stdout, "error: open small failed!\n"); + 607: 51 push %ecx + 608: 51 push %ecx + 609: 68 26 3f 00 00 push $0x3f26 + 60e: ff 35 58 5e 00 00 push 0x5e58 + 614: e8 27 34 00 00 call 3a40 + exit(); + 619: e8 b5 32 00 00 call 38d3 + printf(stdout, "read failed\n"); + 61e: 52 push %edx + 61f: 52 push %edx + 620: 68 6d 42 00 00 push $0x426d + 625: ff 35 58 5e 00 00 push 0x5e58 + 62b: e8 10 34 00 00 call 3a40 + exit(); + 630: e8 9e 32 00 00 call 38d3 + printf(stdout, "unlink small failed\n"); + 635: 50 push %eax + 636: 50 push %eax + 637: 68 54 3f 00 00 push $0x3f54 + 63c: ff 35 58 5e 00 00 push 0x5e58 + 642: e8 f9 33 00 00 call 3a40 + exit(); + 647: e8 87 32 00 00 call 38d3 + printf(stdout, "error: creat small failed!\n"); + 64c: 50 push %eax + 64d: 50 push %eax + 64e: 68 d0 3e 00 00 push $0x3ed0 + 653: ff 35 58 5e 00 00 push 0x5e58 + 659: e8 e2 33 00 00 call 3a40 + exit(); + 65e: e8 70 32 00 00 call 38d3 + 663: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 66a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +00000670 : +void writetest1(void) { + 670: 55 push %ebp + 671: 89 e5 mov %esp,%ebp + 673: 56 push %esi + 674: 53 push %ebx + printf(stdout, "big files test\n"); + 675: 83 ec 08 sub $0x8,%esp + 678: 68 7d 3f 00 00 push $0x3f7d + 67d: ff 35 58 5e 00 00 push 0x5e58 + 683: e8 b8 33 00 00 call 3a40 + fd = open("big", O_CREATE | O_RDWR); + 688: 58 pop %eax + 689: 5a pop %edx + 68a: 68 02 02 00 00 push $0x202 + 68f: 68 f7 3f 00 00 push $0x3ff7 + 694: e8 a2 32 00 00 call 393b + if (fd < 0) { + 699: 83 c4 10 add $0x10,%esp + 69c: 85 c0 test %eax,%eax + 69e: 0f 88 61 01 00 00 js 805 + 6a4: 89 c6 mov %eax,%esi + for (i = 0; i < MAXFILE; i++) { + 6a6: 31 db xor %ebx,%ebx + 6a8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 6af: 90 nop + if (write(fd, buf, 512) != 512) { + 6b0: 83 ec 04 sub $0x4,%esp + ((int*)buf)[0] = i; + 6b3: 89 1d a0 85 00 00 mov %ebx,0x85a0 + if (write(fd, buf, 512) != 512) { + 6b9: 68 00 02 00 00 push $0x200 + 6be: 68 a0 85 00 00 push $0x85a0 + 6c3: 56 push %esi + 6c4: e8 7a 32 00 00 call 3943 + 6c9: 83 c4 10 add $0x10,%esp + 6cc: 3d 00 02 00 00 cmp $0x200,%eax + 6d1: 0f 85 b3 00 00 00 jne 78a + for (i = 0; i < MAXFILE; i++) { + 6d7: 83 c3 01 add $0x1,%ebx + 6da: 81 fb 8c 00 00 00 cmp $0x8c,%ebx + 6e0: 75 ce jne 6b0 + close(fd); + 6e2: 83 ec 0c sub $0xc,%esp + 6e5: 56 push %esi + 6e6: e8 80 32 00 00 call 396b + fd = open("big", O_RDONLY); + 6eb: 5b pop %ebx + 6ec: 5e pop %esi + 6ed: 6a 00 push $0x0 + 6ef: 68 f7 3f 00 00 push $0x3ff7 + 6f4: e8 42 32 00 00 call 393b + if (fd < 0) { + 6f9: 83 c4 10 add $0x10,%esp + fd = open("big", O_RDONLY); + 6fc: 89 c3 mov %eax,%ebx + if (fd < 0) { + 6fe: 85 c0 test %eax,%eax + 700: 0f 88 e8 00 00 00 js 7ee + n = 0; + 706: 31 f6 xor %esi,%esi + 708: eb 1d jmp 727 + 70a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + else if (i != 512) { + 710: 3d 00 02 00 00 cmp $0x200,%eax + 715: 0f 85 9f 00 00 00 jne 7ba + if (((int*)buf)[0] != n) { + 71b: a1 a0 85 00 00 mov 0x85a0,%eax + 720: 39 f0 cmp %esi,%eax + 722: 75 7f jne 7a3 + n++; + 724: 83 c6 01 add $0x1,%esi + i = read(fd, buf, 512); + 727: 83 ec 04 sub $0x4,%esp + 72a: 68 00 02 00 00 push $0x200 + 72f: 68 a0 85 00 00 push $0x85a0 + 734: 53 push %ebx + 735: e8 b1 31 00 00 call 38eb + if (i == 0) { + 73a: 83 c4 10 add $0x10,%esp + 73d: 85 c0 test %eax,%eax + 73f: 75 cf jne 710 + if (n == MAXFILE - 1) { + 741: 81 fe 8b 00 00 00 cmp $0x8b,%esi + 747: 0f 84 86 00 00 00 je 7d3 + close(fd); + 74d: 83 ec 0c sub $0xc,%esp + 750: 53 push %ebx + 751: e8 15 32 00 00 call 396b + if (unlink("big") < 0) { + 756: c7 04 24 f7 3f 00 00 movl $0x3ff7,(%esp) + 75d: e8 f1 31 00 00 call 3953 + 762: 83 c4 10 add $0x10,%esp + 765: 85 c0 test %eax,%eax + 767: 0f 88 af 00 00 00 js 81c + printf(stdout, "big files ok\n"); + 76d: 83 ec 08 sub $0x8,%esp + 770: 68 1e 40 00 00 push $0x401e + 775: ff 35 58 5e 00 00 push 0x5e58 + 77b: e8 c0 32 00 00 call 3a40 +} + 780: 83 c4 10 add $0x10,%esp + 783: 8d 65 f8 lea -0x8(%ebp),%esp + 786: 5b pop %ebx + 787: 5e pop %esi + 788: 5d pop %ebp + 789: c3 ret + printf(stdout, "error: write big file failed\n", i); + 78a: 83 ec 04 sub $0x4,%esp + 78d: 53 push %ebx + 78e: 68 a7 3f 00 00 push $0x3fa7 + 793: ff 35 58 5e 00 00 push 0x5e58 + 799: e8 a2 32 00 00 call 3a40 + exit(); + 79e: e8 30 31 00 00 call 38d3 + printf(stdout, "read content of block %d is %d\n", + 7a3: 50 push %eax + 7a4: 56 push %esi + 7a5: 68 f8 4d 00 00 push $0x4df8 + 7aa: ff 35 58 5e 00 00 push 0x5e58 + 7b0: e8 8b 32 00 00 call 3a40 + exit(); + 7b5: e8 19 31 00 00 call 38d3 + printf(stdout, "read failed %d\n", i); + 7ba: 83 ec 04 sub $0x4,%esp + 7bd: 50 push %eax + 7be: 68 fb 3f 00 00 push $0x3ffb + 7c3: ff 35 58 5e 00 00 push 0x5e58 + 7c9: e8 72 32 00 00 call 3a40 + exit(); + 7ce: e8 00 31 00 00 call 38d3 + printf(stdout, "read only %d blocks from big", n); + 7d3: 52 push %edx + 7d4: 68 8b 00 00 00 push $0x8b + 7d9: 68 de 3f 00 00 push $0x3fde + 7de: ff 35 58 5e 00 00 push 0x5e58 + 7e4: e8 57 32 00 00 call 3a40 + exit(); + 7e9: e8 e5 30 00 00 call 38d3 + printf(stdout, "error: open big failed!\n"); + 7ee: 51 push %ecx + 7ef: 51 push %ecx + 7f0: 68 c5 3f 00 00 push $0x3fc5 + 7f5: ff 35 58 5e 00 00 push 0x5e58 + 7fb: e8 40 32 00 00 call 3a40 + exit(); + 800: e8 ce 30 00 00 call 38d3 + printf(stdout, "error: creat big failed!\n"); + 805: 50 push %eax + 806: 50 push %eax + 807: 68 8d 3f 00 00 push $0x3f8d + 80c: ff 35 58 5e 00 00 push 0x5e58 + 812: e8 29 32 00 00 call 3a40 + exit(); + 817: e8 b7 30 00 00 call 38d3 + printf(stdout, "unlink big failed\n"); + 81c: 50 push %eax + 81d: 50 push %eax + 81e: 68 0b 40 00 00 push $0x400b + 823: ff 35 58 5e 00 00 push 0x5e58 + 829: e8 12 32 00 00 call 3a40 + exit(); + 82e: e8 a0 30 00 00 call 38d3 + 833: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 83a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +00000840 : +void createtest(void) { + 840: 55 push %ebp + 841: 89 e5 mov %esp,%ebp + 843: 53 push %ebx + name[2] = '\0'; + 844: bb 30 00 00 00 mov $0x30,%ebx +void createtest(void) { + 849: 83 ec 0c sub $0xc,%esp + printf(stdout, "many creates, followed by unlink test\n"); + 84c: 68 18 4e 00 00 push $0x4e18 + 851: ff 35 58 5e 00 00 push 0x5e58 + 857: e8 e4 31 00 00 call 3a40 + name[0] = 'a'; + 85c: c6 05 90 85 00 00 61 movb $0x61,0x8590 + name[2] = '\0'; + 863: 83 c4 10 add $0x10,%esp + 866: c6 05 92 85 00 00 00 movb $0x0,0x8592 + for (i = 0; i < 52; i++) { + 86d: 8d 76 00 lea 0x0(%esi),%esi + fd = open(name, O_CREATE | O_RDWR); + 870: 83 ec 08 sub $0x8,%esp + name[1] = '0' + i; + 873: 88 1d 91 85 00 00 mov %bl,0x8591 + for (i = 0; i < 52; i++) { + 879: 83 c3 01 add $0x1,%ebx + fd = open(name, O_CREATE | O_RDWR); + 87c: 68 02 02 00 00 push $0x202 + 881: 68 90 85 00 00 push $0x8590 + 886: e8 b0 30 00 00 call 393b + close(fd); + 88b: 89 04 24 mov %eax,(%esp) + 88e: e8 d8 30 00 00 call 396b + for (i = 0; i < 52; i++) { + 893: 83 c4 10 add $0x10,%esp + 896: 80 fb 64 cmp $0x64,%bl + 899: 75 d5 jne 870 + name[0] = 'a'; + 89b: c6 05 90 85 00 00 61 movb $0x61,0x8590 + name[2] = '\0'; + 8a2: bb 30 00 00 00 mov $0x30,%ebx + 8a7: c6 05 92 85 00 00 00 movb $0x0,0x8592 + for (i = 0; i < 52; i++) { + 8ae: 66 90 xchg %ax,%ax + unlink(name); + 8b0: 83 ec 0c sub $0xc,%esp + name[1] = '0' + i; + 8b3: 88 1d 91 85 00 00 mov %bl,0x8591 + for (i = 0; i < 52; i++) { + 8b9: 83 c3 01 add $0x1,%ebx + unlink(name); + 8bc: 68 90 85 00 00 push $0x8590 + 8c1: e8 8d 30 00 00 call 3953 + for (i = 0; i < 52; i++) { + 8c6: 83 c4 10 add $0x10,%esp + 8c9: 80 fb 64 cmp $0x64,%bl + 8cc: 75 e2 jne 8b0 + printf(stdout, "many creates, followed by unlink; ok\n"); + 8ce: 83 ec 08 sub $0x8,%esp + 8d1: 68 40 4e 00 00 push $0x4e40 + 8d6: ff 35 58 5e 00 00 push 0x5e58 + 8dc: e8 5f 31 00 00 call 3a40 +} + 8e1: 8b 5d fc mov -0x4(%ebp),%ebx + 8e4: 83 c4 10 add $0x10,%esp + 8e7: c9 leave + 8e8: c3 ret + 8e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +000008f0 : +void dirtest(void){ + 8f0: 55 push %ebp + 8f1: 89 e5 mov %esp,%ebp + 8f3: 83 ec 10 sub $0x10,%esp + printf(stdout, "mkdir test\n"); + 8f6: 68 2c 40 00 00 push $0x402c + 8fb: ff 35 58 5e 00 00 push 0x5e58 + 901: e8 3a 31 00 00 call 3a40 + if (mkdir("dir0") < 0) { + 906: c7 04 24 38 40 00 00 movl $0x4038,(%esp) + 90d: e8 51 30 00 00 call 3963 + 912: 83 c4 10 add $0x10,%esp + 915: 85 c0 test %eax,%eax + 917: 78 58 js 971 + if (chdir("dir0") < 0) { + 919: 83 ec 0c sub $0xc,%esp + 91c: 68 38 40 00 00 push $0x4038 + 921: e8 e5 2f 00 00 call 390b + 926: 83 c4 10 add $0x10,%esp + 929: 85 c0 test %eax,%eax + 92b: 0f 88 85 00 00 00 js 9b6 + if (chdir("..") < 0) { + 931: 83 ec 0c sub $0xc,%esp + 934: 68 dd 45 00 00 push $0x45dd + 939: e8 cd 2f 00 00 call 390b + 93e: 83 c4 10 add $0x10,%esp + 941: 85 c0 test %eax,%eax + 943: 78 5a js 99f + if (unlink("dir0") < 0) { + 945: 83 ec 0c sub $0xc,%esp + 948: 68 38 40 00 00 push $0x4038 + 94d: e8 01 30 00 00 call 3953 + 952: 83 c4 10 add $0x10,%esp + 955: 85 c0 test %eax,%eax + 957: 78 2f js 988 + printf(stdout, "mkdir test ok\n"); + 959: 83 ec 08 sub $0x8,%esp + 95c: 68 75 40 00 00 push $0x4075 + 961: ff 35 58 5e 00 00 push 0x5e58 + 967: e8 d4 30 00 00 call 3a40 +} + 96c: 83 c4 10 add $0x10,%esp + 96f: c9 leave + 970: c3 ret + printf(stdout, "mkdir failed\n"); + 971: 50 push %eax + 972: 50 push %eax + 973: 68 68 3d 00 00 push $0x3d68 + 978: ff 35 58 5e 00 00 push 0x5e58 + 97e: e8 bd 30 00 00 call 3a40 + exit(); + 983: e8 4b 2f 00 00 call 38d3 + printf(stdout, "unlink dir0 failed\n"); + 988: 50 push %eax + 989: 50 push %eax + 98a: 68 61 40 00 00 push $0x4061 + 98f: ff 35 58 5e 00 00 push 0x5e58 + 995: e8 a6 30 00 00 call 3a40 + exit(); + 99a: e8 34 2f 00 00 call 38d3 + printf(stdout, "chdir .. failed\n"); + 99f: 52 push %edx + 9a0: 52 push %edx + 9a1: 68 50 40 00 00 push $0x4050 + 9a6: ff 35 58 5e 00 00 push 0x5e58 + 9ac: e8 8f 30 00 00 call 3a40 + exit(); + 9b1: e8 1d 2f 00 00 call 38d3 + printf(stdout, "chdir dir0 failed\n"); + 9b6: 51 push %ecx + 9b7: 51 push %ecx + 9b8: 68 3d 40 00 00 push $0x403d + 9bd: ff 35 58 5e 00 00 push 0x5e58 + 9c3: e8 78 30 00 00 call 3a40 + exit(); + 9c8: e8 06 2f 00 00 call 38d3 + 9cd: 8d 76 00 lea 0x0(%esi),%esi + +000009d0 : +void exectest(void) { + 9d0: 55 push %ebp + 9d1: 89 e5 mov %esp,%ebp + 9d3: 83 ec 10 sub $0x10,%esp + printf(stdout, "exec test\n"); + 9d6: 68 84 40 00 00 push $0x4084 + 9db: ff 35 58 5e 00 00 push 0x5e58 + 9e1: e8 5a 30 00 00 call 3a40 + if (exec("echo", echoargv) < 0) { + 9e6: 5a pop %edx + 9e7: 59 pop %ecx + 9e8: 68 5c 5e 00 00 push $0x5e5c + 9ed: 68 4d 3e 00 00 push $0x3e4d + 9f2: e8 04 2f 00 00 call 38fb + 9f7: 83 c4 10 add $0x10,%esp + 9fa: 85 c0 test %eax,%eax + 9fc: 78 02 js a00 +} + 9fe: c9 leave + 9ff: c3 ret + printf(stdout, "exec echo failed\n"); + a00: 50 push %eax + a01: 50 push %eax + a02: 68 8f 40 00 00 push $0x408f + a07: ff 35 58 5e 00 00 push 0x5e58 + a0d: e8 2e 30 00 00 call 3a40 + exit(); + a12: e8 bc 2e 00 00 call 38d3 + a17: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + a1e: 66 90 xchg %ax,%ax + +00000a20 : +void pipe1(void) { + a20: 55 push %ebp + a21: 89 e5 mov %esp,%ebp + a23: 57 push %edi + a24: 56 push %esi + if (pipe(fds) != 0) { + a25: 8d 45 e0 lea -0x20(%ebp),%eax +void pipe1(void) { + a28: 53 push %ebx + a29: 83 ec 38 sub $0x38,%esp + if (pipe(fds) != 0) { + a2c: 50 push %eax + a2d: e8 b1 2e 00 00 call 38e3 + a32: 83 c4 10 add $0x10,%esp + a35: 85 c0 test %eax,%eax + a37: 0f 85 34 01 00 00 jne b71 + pid = fork(); + a3d: e8 89 2e 00 00 call 38cb + if (pid == 0) { + a42: 85 c0 test %eax,%eax + a44: 0f 84 85 00 00 00 je acf + else if (pid > 0) { + a4a: 0f 8e 34 01 00 00 jle b84 + close(fds[1]); + a50: 83 ec 0c sub $0xc,%esp + a53: ff 75 e4 push -0x1c(%ebp) + seq = 0; + a56: 31 db xor %ebx,%ebx + cc = 1; + a58: be 01 00 00 00 mov $0x1,%esi + close(fds[1]); + a5d: e8 09 2f 00 00 call 396b + total = 0; + a62: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%ebp) + while ((n = read(fds[0], buf, cc)) > 0) { + a69: 83 c4 10 add $0x10,%esp + a6c: 83 ec 04 sub $0x4,%esp + a6f: 56 push %esi + a70: 68 a0 85 00 00 push $0x85a0 + a75: ff 75 e0 push -0x20(%ebp) + a78: e8 6e 2e 00 00 call 38eb + a7d: 83 c4 10 add $0x10,%esp + a80: 89 c7 mov %eax,%edi + a82: 85 c0 test %eax,%eax + a84: 0f 8e a3 00 00 00 jle b2d + a8a: 8d 0c 1f lea (%edi,%ebx,1),%ecx + for (i = 0; i < n; i++) { + a8d: 31 c0 xor %eax,%eax + a8f: 90 nop + if ((buf[i] & 0xff) != (seq++ & 0xff)) { + a90: 89 da mov %ebx,%edx + a92: 83 c3 01 add $0x1,%ebx + a95: 38 90 a0 85 00 00 cmp %dl,0x85a0(%eax) + a9b: 75 18 jne ab5 + for (i = 0; i < n; i++) { + a9d: 83 c0 01 add $0x1,%eax + aa0: 39 d9 cmp %ebx,%ecx + aa2: 75 ec jne a90 + cc = cc * 2; + aa4: 01 f6 add %esi,%esi + aa6: b8 00 20 00 00 mov $0x2000,%eax + total += n; + aab: 01 7d d4 add %edi,-0x2c(%ebp) + aae: 39 c6 cmp %eax,%esi + ab0: 0f 4f f0 cmovg %eax,%esi + ab3: eb b7 jmp a6c + printf(1, "pipe1 oops 2\n"); + ab5: 83 ec 08 sub $0x8,%esp + ab8: 68 be 40 00 00 push $0x40be + abd: 6a 01 push $0x1 + abf: e8 7c 2f 00 00 call 3a40 + ac4: 83 c4 10 add $0x10,%esp +} + ac7: 8d 65 f4 lea -0xc(%ebp),%esp + aca: 5b pop %ebx + acb: 5e pop %esi + acc: 5f pop %edi + acd: 5d pop %ebp + ace: c3 ret + close(fds[0]); + acf: 83 ec 0c sub $0xc,%esp + ad2: ff 75 e0 push -0x20(%ebp) + seq = 0; + ad5: 31 db xor %ebx,%ebx + close(fds[0]); + ad7: e8 8f 2e 00 00 call 396b + adc: 83 c4 10 add $0x10,%esp + for (i = 0; i < 1033; i++) { + adf: 31 c0 xor %eax,%eax + ae1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + buf[i] = seq++; + ae8: 8d 14 18 lea (%eax,%ebx,1),%edx + for (i = 0; i < 1033; i++) { + aeb: 83 c0 01 add $0x1,%eax + buf[i] = seq++; + aee: 88 90 9f 85 00 00 mov %dl,0x859f(%eax) + for (i = 0; i < 1033; i++) { + af4: 3d 09 04 00 00 cmp $0x409,%eax + af9: 75 ed jne ae8 + if (write(fds[1], buf, 1033) != 1033) { + afb: 83 ec 04 sub $0x4,%esp + buf[i] = seq++; + afe: 81 c3 09 04 00 00 add $0x409,%ebx + if (write(fds[1], buf, 1033) != 1033) { + b04: 68 09 04 00 00 push $0x409 + b09: 68 a0 85 00 00 push $0x85a0 + b0e: ff 75 e4 push -0x1c(%ebp) + b11: e8 2d 2e 00 00 call 3943 + b16: 83 c4 10 add $0x10,%esp + b19: 3d 09 04 00 00 cmp $0x409,%eax + b1e: 75 77 jne b97 + for (n = 0; n < 5; n++) { + b20: 81 fb 2d 14 00 00 cmp $0x142d,%ebx + b26: 75 b7 jne adf + exit(); + b28: e8 a6 2d 00 00 call 38d3 + if (total != 5 * 1033) { + b2d: 81 7d d4 2d 14 00 00 cmpl $0x142d,-0x2c(%ebp) + b34: 75 26 jne b5c + close(fds[0]); + b36: 83 ec 0c sub $0xc,%esp + b39: ff 75 e0 push -0x20(%ebp) + b3c: e8 2a 2e 00 00 call 396b + wait(); + b41: e8 95 2d 00 00 call 38db + printf(1, "pipe1 ok\n"); + b46: 5a pop %edx + b47: 59 pop %ecx + b48: 68 e3 40 00 00 push $0x40e3 + b4d: 6a 01 push $0x1 + b4f: e8 ec 2e 00 00 call 3a40 + b54: 83 c4 10 add $0x10,%esp + b57: e9 6b ff ff ff jmp ac7 + printf(1, "pipe1 oops 3 total %d\n", total); + b5c: 53 push %ebx + b5d: ff 75 d4 push -0x2c(%ebp) + b60: 68 cc 40 00 00 push $0x40cc + b65: 6a 01 push $0x1 + b67: e8 d4 2e 00 00 call 3a40 + exit(); + b6c: e8 62 2d 00 00 call 38d3 + printf(1, "pipe() failed\n"); + b71: 57 push %edi + b72: 57 push %edi + b73: 68 a1 40 00 00 push $0x40a1 + b78: 6a 01 push $0x1 + b7a: e8 c1 2e 00 00 call 3a40 + exit(); + b7f: e8 4f 2d 00 00 call 38d3 + printf(1, "fork() failed\n"); + b84: 50 push %eax + b85: 50 push %eax + b86: 68 ed 40 00 00 push $0x40ed + b8b: 6a 01 push $0x1 + b8d: e8 ae 2e 00 00 call 3a40 + exit(); + b92: e8 3c 2d 00 00 call 38d3 + printf(1, "pipe1 oops 1\n"); + b97: 56 push %esi + b98: 56 push %esi + b99: 68 b0 40 00 00 push $0x40b0 + b9e: 6a 01 push $0x1 + ba0: e8 9b 2e 00 00 call 3a40 + exit(); + ba5: e8 29 2d 00 00 call 38d3 + baa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +00000bb0 : +void preempt(void) { + bb0: 55 push %ebp + bb1: 89 e5 mov %esp,%ebp + bb3: 57 push %edi + bb4: 56 push %esi + bb5: 53 push %ebx + bb6: 83 ec 24 sub $0x24,%esp + printf(1, "preempt: "); + bb9: 68 fc 40 00 00 push $0x40fc + bbe: 6a 01 push $0x1 + bc0: e8 7b 2e 00 00 call 3a40 + pid1 = fork(); + bc5: e8 01 2d 00 00 call 38cb + if (pid1 == 0) { + bca: 83 c4 10 add $0x10,%esp + bcd: 85 c0 test %eax,%eax + bcf: 75 07 jne bd8 + for (;;) { + bd1: eb fe jmp bd1 + bd3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + bd7: 90 nop + bd8: 89 c3 mov %eax,%ebx + pid2 = fork(); + bda: e8 ec 2c 00 00 call 38cb + bdf: 89 c6 mov %eax,%esi + if (pid2 == 0) { + be1: 85 c0 test %eax,%eax + be3: 75 0b jne bf0 + for (;;) { + be5: eb fe jmp be5 + be7: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + bee: 66 90 xchg %ax,%ax + pipe(pfds); + bf0: 83 ec 0c sub $0xc,%esp + bf3: 8d 45 e0 lea -0x20(%ebp),%eax + bf6: 50 push %eax + bf7: e8 e7 2c 00 00 call 38e3 + pid3 = fork(); + bfc: e8 ca 2c 00 00 call 38cb + if (pid3 == 0) { + c01: 83 c4 10 add $0x10,%esp + pid3 = fork(); + c04: 89 c7 mov %eax,%edi + if (pid3 == 0) { + c06: 85 c0 test %eax,%eax + c08: 75 3e jne c48 + close(pfds[0]); + c0a: 83 ec 0c sub $0xc,%esp + c0d: ff 75 e0 push -0x20(%ebp) + c10: e8 56 2d 00 00 call 396b + if (write(pfds[1], "x", 1) != 1) { + c15: 83 c4 0c add $0xc,%esp + c18: 6a 01 push $0x1 + c1a: 68 c1 46 00 00 push $0x46c1 + c1f: ff 75 e4 push -0x1c(%ebp) + c22: e8 1c 2d 00 00 call 3943 + c27: 83 c4 10 add $0x10,%esp + c2a: 83 f8 01 cmp $0x1,%eax + c2d: 0f 85 b8 00 00 00 jne ceb + close(pfds[1]); + c33: 83 ec 0c sub $0xc,%esp + c36: ff 75 e4 push -0x1c(%ebp) + c39: e8 2d 2d 00 00 call 396b + c3e: 83 c4 10 add $0x10,%esp + for (;;) { + c41: eb fe jmp c41 + c43: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + c47: 90 nop + close(pfds[1]); + c48: 83 ec 0c sub $0xc,%esp + c4b: ff 75 e4 push -0x1c(%ebp) + c4e: e8 18 2d 00 00 call 396b + if (read(pfds[0], buf, sizeof(buf)) != 1) { + c53: 83 c4 0c add $0xc,%esp + c56: 68 00 20 00 00 push $0x2000 + c5b: 68 a0 85 00 00 push $0x85a0 + c60: ff 75 e0 push -0x20(%ebp) + c63: e8 83 2c 00 00 call 38eb + c68: 83 c4 10 add $0x10,%esp + c6b: 83 f8 01 cmp $0x1,%eax + c6e: 75 67 jne cd7 + close(pfds[0]); + c70: 83 ec 0c sub $0xc,%esp + c73: ff 75 e0 push -0x20(%ebp) + c76: e8 f0 2c 00 00 call 396b + printf(1, "kill... "); + c7b: 58 pop %eax + c7c: 5a pop %edx + c7d: 68 2d 41 00 00 push $0x412d + c82: 6a 01 push $0x1 + c84: e8 b7 2d 00 00 call 3a40 + kill(pid1); + c89: 89 1c 24 mov %ebx,(%esp) + c8c: e8 62 2c 00 00 call 38f3 + kill(pid2); + c91: 89 34 24 mov %esi,(%esp) + c94: e8 5a 2c 00 00 call 38f3 + kill(pid3); + c99: 89 3c 24 mov %edi,(%esp) + c9c: e8 52 2c 00 00 call 38f3 + printf(1, "wait... "); + ca1: 59 pop %ecx + ca2: 5b pop %ebx + ca3: 68 36 41 00 00 push $0x4136 + ca8: 6a 01 push $0x1 + caa: e8 91 2d 00 00 call 3a40 + wait(); + caf: e8 27 2c 00 00 call 38db + wait(); + cb4: e8 22 2c 00 00 call 38db + wait(); + cb9: e8 1d 2c 00 00 call 38db + printf(1, "preempt ok\n"); + cbe: 5e pop %esi + cbf: 5f pop %edi + cc0: 68 3f 41 00 00 push $0x413f + cc5: 6a 01 push $0x1 + cc7: e8 74 2d 00 00 call 3a40 + ccc: 83 c4 10 add $0x10,%esp +} + ccf: 8d 65 f4 lea -0xc(%ebp),%esp + cd2: 5b pop %ebx + cd3: 5e pop %esi + cd4: 5f pop %edi + cd5: 5d pop %ebp + cd6: c3 ret + printf(1, "preempt read error"); + cd7: 83 ec 08 sub $0x8,%esp + cda: 68 1a 41 00 00 push $0x411a + cdf: 6a 01 push $0x1 + ce1: e8 5a 2d 00 00 call 3a40 + ce6: 83 c4 10 add $0x10,%esp + ce9: eb e4 jmp ccf + printf(1, "preempt write error"); + ceb: 83 ec 08 sub $0x8,%esp + cee: 68 06 41 00 00 push $0x4106 + cf3: 6a 01 push $0x1 + cf5: e8 46 2d 00 00 call 3a40 + cfa: 83 c4 10 add $0x10,%esp + cfd: e9 31 ff ff ff jmp c33 + d02: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + d09: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000d10 : +void exitwait(void) { + d10: 55 push %ebp + d11: 89 e5 mov %esp,%ebp + d13: 56 push %esi + d14: be 64 00 00 00 mov $0x64,%esi + d19: 53 push %ebx + d1a: eb 14 jmp d30 + d1c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (pid) { + d20: 74 68 je d8a + if (wait() != pid) { + d22: e8 b4 2b 00 00 call 38db + d27: 39 d8 cmp %ebx,%eax + d29: 75 2d jne d58 + for (i = 0; i < 100; i++) { + d2b: 83 ee 01 sub $0x1,%esi + d2e: 74 41 je d71 + pid = fork(); + d30: e8 96 2b 00 00 call 38cb + d35: 89 c3 mov %eax,%ebx + if (pid < 0) { + d37: 85 c0 test %eax,%eax + d39: 79 e5 jns d20 + printf(1, "fork failed\n"); + d3b: 83 ec 08 sub $0x8,%esp + d3e: 68 a9 4c 00 00 push $0x4ca9 + d43: 6a 01 push $0x1 + d45: e8 f6 2c 00 00 call 3a40 + return; + d4a: 83 c4 10 add $0x10,%esp +} + d4d: 8d 65 f8 lea -0x8(%ebp),%esp + d50: 5b pop %ebx + d51: 5e pop %esi + d52: 5d pop %ebp + d53: c3 ret + d54: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + printf(1, "wait wrong pid\n"); + d58: 83 ec 08 sub $0x8,%esp + d5b: 68 4b 41 00 00 push $0x414b + d60: 6a 01 push $0x1 + d62: e8 d9 2c 00 00 call 3a40 + return; + d67: 83 c4 10 add $0x10,%esp +} + d6a: 8d 65 f8 lea -0x8(%ebp),%esp + d6d: 5b pop %ebx + d6e: 5e pop %esi + d6f: 5d pop %ebp + d70: c3 ret + printf(1, "exitwait ok\n"); + d71: 83 ec 08 sub $0x8,%esp + d74: 68 5b 41 00 00 push $0x415b + d79: 6a 01 push $0x1 + d7b: e8 c0 2c 00 00 call 3a40 + d80: 83 c4 10 add $0x10,%esp +} + d83: 8d 65 f8 lea -0x8(%ebp),%esp + d86: 5b pop %ebx + d87: 5e pop %esi + d88: 5d pop %ebp + d89: c3 ret + exit(); + d8a: e8 44 2b 00 00 call 38d3 + d8f: 90 nop + +00000d90 : +void mem(void) { + d90: 55 push %ebp + d91: 89 e5 mov %esp,%ebp + d93: 56 push %esi + d94: 31 f6 xor %esi,%esi + d96: 53 push %ebx + printf(1, "mem test\n"); + d97: 83 ec 08 sub $0x8,%esp + d9a: 68 68 41 00 00 push $0x4168 + d9f: 6a 01 push $0x1 + da1: e8 9a 2c 00 00 call 3a40 + ppid = getpid(); + da6: e8 70 2b 00 00 call 391b + dab: 89 c3 mov %eax,%ebx + if ((pid = fork()) == 0) { + dad: e8 19 2b 00 00 call 38cb + db2: 83 c4 10 add $0x10,%esp + db5: 85 c0 test %eax,%eax + db7: 74 0b je dc4 + db9: e9 8a 00 00 00 jmp e48 + dbe: 66 90 xchg %ax,%ax + *(char**)m2 = m1; + dc0: 89 30 mov %esi,(%eax) + dc2: 89 c6 mov %eax,%esi + while ((m2 = malloc(10001)) != 0) { + dc4: 83 ec 0c sub $0xc,%esp + dc7: 68 11 27 00 00 push $0x2711 + dcc: e8 9f 2e 00 00 call 3c70 + dd1: 83 c4 10 add $0x10,%esp + dd4: 85 c0 test %eax,%eax + dd6: 75 e8 jne dc0 + while (m1) { + dd8: 85 f6 test %esi,%esi + dda: 74 18 je df4 + ddc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + m2 = *(char**)m1; + de0: 89 f0 mov %esi,%eax + free(m1); + de2: 83 ec 0c sub $0xc,%esp + m2 = *(char**)m1; + de5: 8b 36 mov (%esi),%esi + free(m1); + de7: 50 push %eax + de8: e8 f3 2d 00 00 call 3be0 + while (m1) { + ded: 83 c4 10 add $0x10,%esp + df0: 85 f6 test %esi,%esi + df2: 75 ec jne de0 + m1 = malloc(1024 * 20); + df4: 83 ec 0c sub $0xc,%esp + df7: 68 00 50 00 00 push $0x5000 + dfc: e8 6f 2e 00 00 call 3c70 + if (m1 == 0) { + e01: 83 c4 10 add $0x10,%esp + e04: 85 c0 test %eax,%eax + e06: 74 20 je e28 + free(m1); + e08: 83 ec 0c sub $0xc,%esp + e0b: 50 push %eax + e0c: e8 cf 2d 00 00 call 3be0 + printf(1, "mem ok\n"); + e11: 58 pop %eax + e12: 5a pop %edx + e13: 68 8c 41 00 00 push $0x418c + e18: 6a 01 push $0x1 + e1a: e8 21 2c 00 00 call 3a40 + exit(); + e1f: e8 af 2a 00 00 call 38d3 + e24: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + printf(1, "couldn't allocate mem?!!\n"); + e28: 83 ec 08 sub $0x8,%esp + e2b: 68 72 41 00 00 push $0x4172 + e30: 6a 01 push $0x1 + e32: e8 09 2c 00 00 call 3a40 + kill(ppid); + e37: 89 1c 24 mov %ebx,(%esp) + e3a: e8 b4 2a 00 00 call 38f3 + exit(); + e3f: e8 8f 2a 00 00 call 38d3 + e44: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi +} + e48: 8d 65 f8 lea -0x8(%ebp),%esp + e4b: 5b pop %ebx + e4c: 5e pop %esi + e4d: 5d pop %ebp + wait(); + e4e: e9 88 2a 00 00 jmp 38db + e53: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + e5a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +00000e60 : +void sharedfd(void) { + e60: 55 push %ebp + e61: 89 e5 mov %esp,%ebp + e63: 57 push %edi + e64: 56 push %esi + e65: 53 push %ebx + e66: 83 ec 34 sub $0x34,%esp + printf(1, "sharedfd test\n"); + e69: 68 94 41 00 00 push $0x4194 + e6e: 6a 01 push $0x1 + e70: e8 cb 2b 00 00 call 3a40 + unlink("sharedfd"); + e75: c7 04 24 a3 41 00 00 movl $0x41a3,(%esp) + e7c: e8 d2 2a 00 00 call 3953 + fd = open("sharedfd", O_CREATE | O_RDWR); + e81: 5b pop %ebx + e82: 5e pop %esi + e83: 68 02 02 00 00 push $0x202 + e88: 68 a3 41 00 00 push $0x41a3 + e8d: e8 a9 2a 00 00 call 393b + if (fd < 0) { + e92: 83 c4 10 add $0x10,%esp + e95: 85 c0 test %eax,%eax + e97: 0f 88 2a 01 00 00 js fc7 + e9d: 89 c7 mov %eax,%edi + memset(buf, pid == 0 ? 'c' : 'p', sizeof(buf)); + e9f: 8d 75 de lea -0x22(%ebp),%esi + ea2: bb e8 03 00 00 mov $0x3e8,%ebx + pid = fork(); + ea7: e8 1f 2a 00 00 call 38cb + memset(buf, pid == 0 ? 'c' : 'p', sizeof(buf)); + eac: 83 f8 01 cmp $0x1,%eax + pid = fork(); + eaf: 89 45 d4 mov %eax,-0x2c(%ebp) + memset(buf, pid == 0 ? 'c' : 'p', sizeof(buf)); + eb2: 19 c0 sbb %eax,%eax + eb4: 83 ec 04 sub $0x4,%esp + eb7: 83 e0 f3 and $0xfffffff3,%eax + eba: 6a 0a push $0xa + ebc: 83 c0 70 add $0x70,%eax + ebf: 50 push %eax + ec0: 56 push %esi + ec1: e8 7a 28 00 00 call 3740 + ec6: 83 c4 10 add $0x10,%esp + ec9: eb 0a jmp ed5 + ecb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + ecf: 90 nop + for (i = 0; i < 1000; i++) { + ed0: 83 eb 01 sub $0x1,%ebx + ed3: 74 26 je efb + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { + ed5: 83 ec 04 sub $0x4,%esp + ed8: 6a 0a push $0xa + eda: 56 push %esi + edb: 57 push %edi + edc: e8 62 2a 00 00 call 3943 + ee1: 83 c4 10 add $0x10,%esp + ee4: 83 f8 0a cmp $0xa,%eax + ee7: 74 e7 je ed0 + printf(1, "fstests: write sharedfd failed\n"); + ee9: 83 ec 08 sub $0x8,%esp + eec: 68 94 4e 00 00 push $0x4e94 + ef1: 6a 01 push $0x1 + ef3: e8 48 2b 00 00 call 3a40 + break; + ef8: 83 c4 10 add $0x10,%esp + if (pid == 0) { + efb: 8b 4d d4 mov -0x2c(%ebp),%ecx + efe: 85 c9 test %ecx,%ecx + f00: 0f 84 f5 00 00 00 je ffb + wait(); + f06: e8 d0 29 00 00 call 38db + close(fd); + f0b: 83 ec 0c sub $0xc,%esp + nc = np = 0; + f0e: 31 db xor %ebx,%ebx + close(fd); + f10: 57 push %edi + f11: 8d 7d e8 lea -0x18(%ebp),%edi + f14: e8 52 2a 00 00 call 396b + fd = open("sharedfd", 0); + f19: 58 pop %eax + f1a: 5a pop %edx + f1b: 6a 00 push $0x0 + f1d: 68 a3 41 00 00 push $0x41a3 + f22: e8 14 2a 00 00 call 393b + if (fd < 0) { + f27: 83 c4 10 add $0x10,%esp + nc = np = 0; + f2a: 31 d2 xor %edx,%edx + fd = open("sharedfd", 0); + f2c: 89 45 d0 mov %eax,-0x30(%ebp) + if (fd < 0) { + f2f: 85 c0 test %eax,%eax + f31: 0f 88 aa 00 00 00 js fe1 + f37: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + f3e: 66 90 xchg %ax,%ax + while ((n = read(fd, buf, sizeof(buf))) > 0) { + f40: 83 ec 04 sub $0x4,%esp + f43: 89 55 d4 mov %edx,-0x2c(%ebp) + f46: 6a 0a push $0xa + f48: 56 push %esi + f49: ff 75 d0 push -0x30(%ebp) + f4c: e8 9a 29 00 00 call 38eb + f51: 83 c4 10 add $0x10,%esp + f54: 85 c0 test %eax,%eax + f56: 7e 28 jle f80 + f58: 8b 55 d4 mov -0x2c(%ebp),%edx + f5b: 89 f0 mov %esi,%eax + f5d: eb 13 jmp f72 + f5f: 90 nop + np++; + f60: 80 f9 70 cmp $0x70,%cl + f63: 0f 94 c1 sete %cl + f66: 0f b6 c9 movzbl %cl,%ecx + f69: 01 cb add %ecx,%ebx + for (i = 0; i < sizeof(buf); i++) { + f6b: 83 c0 01 add $0x1,%eax + f6e: 39 f8 cmp %edi,%eax + f70: 74 ce je f40 + if (buf[i] == 'c') { + f72: 0f b6 08 movzbl (%eax),%ecx + f75: 80 f9 63 cmp $0x63,%cl + f78: 75 e6 jne f60 + nc++; + f7a: 83 c2 01 add $0x1,%edx + if (buf[i] == 'p') { + f7d: eb ec jmp f6b + f7f: 90 nop + close(fd); + f80: 83 ec 0c sub $0xc,%esp + f83: ff 75 d0 push -0x30(%ebp) + f86: e8 e0 29 00 00 call 396b + unlink("sharedfd"); + f8b: c7 04 24 a3 41 00 00 movl $0x41a3,(%esp) + f92: e8 bc 29 00 00 call 3953 + if (nc == 10000 && np == 10000) { + f97: 8b 55 d4 mov -0x2c(%ebp),%edx + f9a: 83 c4 10 add $0x10,%esp + f9d: 81 fa 10 27 00 00 cmp $0x2710,%edx + fa3: 75 5b jne 1000 + fa5: 81 fb 10 27 00 00 cmp $0x2710,%ebx + fab: 75 53 jne 1000 + printf(1, "sharedfd ok\n"); + fad: 83 ec 08 sub $0x8,%esp + fb0: 68 ac 41 00 00 push $0x41ac + fb5: 6a 01 push $0x1 + fb7: e8 84 2a 00 00 call 3a40 + fbc: 83 c4 10 add $0x10,%esp +} + fbf: 8d 65 f4 lea -0xc(%ebp),%esp + fc2: 5b pop %ebx + fc3: 5e pop %esi + fc4: 5f pop %edi + fc5: 5d pop %ebp + fc6: c3 ret + printf(1, "fstests: cannot open sharedfd for writing"); + fc7: 83 ec 08 sub $0x8,%esp + fca: 68 68 4e 00 00 push $0x4e68 + fcf: 6a 01 push $0x1 + fd1: e8 6a 2a 00 00 call 3a40 + return; + fd6: 83 c4 10 add $0x10,%esp +} + fd9: 8d 65 f4 lea -0xc(%ebp),%esp + fdc: 5b pop %ebx + fdd: 5e pop %esi + fde: 5f pop %edi + fdf: 5d pop %ebp + fe0: c3 ret + printf(1, "fstests: cannot open sharedfd for reading\n"); + fe1: 83 ec 08 sub $0x8,%esp + fe4: 68 b4 4e 00 00 push $0x4eb4 + fe9: 6a 01 push $0x1 + feb: e8 50 2a 00 00 call 3a40 + return; + ff0: 83 c4 10 add $0x10,%esp +} + ff3: 8d 65 f4 lea -0xc(%ebp),%esp + ff6: 5b pop %ebx + ff7: 5e pop %esi + ff8: 5f pop %edi + ff9: 5d pop %ebp + ffa: c3 ret + exit(); + ffb: e8 d3 28 00 00 call 38d3 + printf(1, "sharedfd oops %d %d\n", nc, np); + 1000: 53 push %ebx + 1001: 52 push %edx + 1002: 68 b9 41 00 00 push $0x41b9 + 1007: 6a 01 push $0x1 + 1009: e8 32 2a 00 00 call 3a40 + exit(); + 100e: e8 c0 28 00 00 call 38d3 + 1013: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 101a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +00001020 : +void fourfiles(void) { + 1020: 55 push %ebp + 1021: 89 e5 mov %esp,%ebp + 1023: 57 push %edi + 1024: 56 push %esi + printf(1, "fourfiles test\n"); + 1025: be ce 41 00 00 mov $0x41ce,%esi +void fourfiles(void) { + 102a: 53 push %ebx + for (pi = 0; pi < 4; pi++) { + 102b: 31 db xor %ebx,%ebx +void fourfiles(void) { + 102d: 83 ec 34 sub $0x34,%esp + char *names[] = { "f0", "f1", "f2", "f3" }; + 1030: c7 45 d8 ce 41 00 00 movl $0x41ce,-0x28(%ebp) + printf(1, "fourfiles test\n"); + 1037: 68 d4 41 00 00 push $0x41d4 + 103c: 6a 01 push $0x1 + char *names[] = { "f0", "f1", "f2", "f3" }; + 103e: c7 45 dc 17 43 00 00 movl $0x4317,-0x24(%ebp) + 1045: c7 45 e0 1b 43 00 00 movl $0x431b,-0x20(%ebp) + 104c: c7 45 e4 d1 41 00 00 movl $0x41d1,-0x1c(%ebp) + printf(1, "fourfiles test\n"); + 1053: e8 e8 29 00 00 call 3a40 + 1058: 83 c4 10 add $0x10,%esp + unlink(fname); + 105b: 83 ec 0c sub $0xc,%esp + 105e: 56 push %esi + 105f: e8 ef 28 00 00 call 3953 + pid = fork(); + 1064: e8 62 28 00 00 call 38cb + if (pid < 0) { + 1069: 83 c4 10 add $0x10,%esp + 106c: 85 c0 test %eax,%eax + 106e: 0f 88 64 01 00 00 js 11d8 + if (pid == 0) { + 1074: 0f 84 e9 00 00 00 je 1163 + for (pi = 0; pi < 4; pi++) { + 107a: 83 c3 01 add $0x1,%ebx + 107d: 83 fb 04 cmp $0x4,%ebx + 1080: 74 06 je 1088 + fname = names[pi]; + 1082: 8b 74 9d d8 mov -0x28(%ebp,%ebx,4),%esi + 1086: eb d3 jmp 105b + wait(); + 1088: e8 4e 28 00 00 call 38db + for (i = 0; i < 2; i++) { + 108d: 31 f6 xor %esi,%esi + wait(); + 108f: e8 47 28 00 00 call 38db + 1094: e8 42 28 00 00 call 38db + 1099: e8 3d 28 00 00 call 38db + fname = names[i]; + 109e: 8b 44 b5 d8 mov -0x28(%ebp,%esi,4),%eax + fd = open(fname, 0); + 10a2: 83 ec 08 sub $0x8,%esp + total = 0; + 10a5: 31 db xor %ebx,%ebx + fd = open(fname, 0); + 10a7: 6a 00 push $0x0 + 10a9: 50 push %eax + fname = names[i]; + 10aa: 89 45 d0 mov %eax,-0x30(%ebp) + fd = open(fname, 0); + 10ad: e8 89 28 00 00 call 393b + while ((n = read(fd, buf, sizeof(buf))) > 0) { + 10b2: 83 c4 10 add $0x10,%esp + fd = open(fname, 0); + 10b5: 89 45 d4 mov %eax,-0x2c(%ebp) + while ((n = read(fd, buf, sizeof(buf))) > 0) { + 10b8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 10bf: 90 nop + 10c0: 83 ec 04 sub $0x4,%esp + 10c3: 68 00 20 00 00 push $0x2000 + 10c8: 68 a0 85 00 00 push $0x85a0 + 10cd: ff 75 d4 push -0x2c(%ebp) + 10d0: e8 16 28 00 00 call 38eb + 10d5: 83 c4 10 add $0x10,%esp + 10d8: 89 c7 mov %eax,%edi + 10da: 85 c0 test %eax,%eax + 10dc: 7e 20 jle 10fe + for (j = 0; j < n; j++) { + 10de: 31 c0 xor %eax,%eax + if (buf[j] != '0' + i) { + 10e0: 83 fe 01 cmp $0x1,%esi + 10e3: 0f be 88 a0 85 00 00 movsbl 0x85a0(%eax),%ecx + 10ea: 19 d2 sbb %edx,%edx + 10ec: 83 c2 31 add $0x31,%edx + 10ef: 39 d1 cmp %edx,%ecx + 10f1: 75 5c jne 114f + for (j = 0; j < n; j++) { + 10f3: 83 c0 01 add $0x1,%eax + 10f6: 39 c7 cmp %eax,%edi + 10f8: 75 e6 jne 10e0 + total += n; + 10fa: 01 fb add %edi,%ebx + 10fc: eb c2 jmp 10c0 + close(fd); + 10fe: 83 ec 0c sub $0xc,%esp + 1101: ff 75 d4 push -0x2c(%ebp) + 1104: e8 62 28 00 00 call 396b + if (total != 12 * 500) { + 1109: 83 c4 10 add $0x10,%esp + 110c: 81 fb 70 17 00 00 cmp $0x1770,%ebx + 1112: 0f 85 d4 00 00 00 jne 11ec + unlink(fname); + 1118: 83 ec 0c sub $0xc,%esp + 111b: ff 75 d0 push -0x30(%ebp) + 111e: e8 30 28 00 00 call 3953 + for (i = 0; i < 2; i++) { + 1123: 83 c4 10 add $0x10,%esp + 1126: 83 fe 01 cmp $0x1,%esi + 1129: 75 1a jne 1145 + printf(1, "fourfiles ok\n"); + 112b: 83 ec 08 sub $0x8,%esp + 112e: 68 12 42 00 00 push $0x4212 + 1133: 6a 01 push $0x1 + 1135: e8 06 29 00 00 call 3a40 +} + 113a: 83 c4 10 add $0x10,%esp + 113d: 8d 65 f4 lea -0xc(%ebp),%esp + 1140: 5b pop %ebx + 1141: 5e pop %esi + 1142: 5f pop %edi + 1143: 5d pop %ebp + 1144: c3 ret + 1145: be 01 00 00 00 mov $0x1,%esi + 114a: e9 4f ff ff ff jmp 109e + printf(1, "wrong char\n"); + 114f: 83 ec 08 sub $0x8,%esp + 1152: 68 f5 41 00 00 push $0x41f5 + 1157: 6a 01 push $0x1 + 1159: e8 e2 28 00 00 call 3a40 + exit(); + 115e: e8 70 27 00 00 call 38d3 + fd = open(fname, O_CREATE | O_RDWR); + 1163: 83 ec 08 sub $0x8,%esp + 1166: 68 02 02 00 00 push $0x202 + 116b: 56 push %esi + 116c: e8 ca 27 00 00 call 393b + if (fd < 0) { + 1171: 83 c4 10 add $0x10,%esp + fd = open(fname, O_CREATE | O_RDWR); + 1174: 89 c6 mov %eax,%esi + if (fd < 0) { + 1176: 85 c0 test %eax,%eax + 1178: 78 45 js 11bf + memset(buf, '0' + pi, 512); + 117a: 83 ec 04 sub $0x4,%esp + 117d: 83 c3 30 add $0x30,%ebx + 1180: 68 00 02 00 00 push $0x200 + 1185: 53 push %ebx + 1186: bb 0c 00 00 00 mov $0xc,%ebx + 118b: 68 a0 85 00 00 push $0x85a0 + 1190: e8 ab 25 00 00 call 3740 + 1195: 83 c4 10 add $0x10,%esp + if ((n = write(fd, buf, 500)) != 500) { + 1198: 83 ec 04 sub $0x4,%esp + 119b: 68 f4 01 00 00 push $0x1f4 + 11a0: 68 a0 85 00 00 push $0x85a0 + 11a5: 56 push %esi + 11a6: e8 98 27 00 00 call 3943 + 11ab: 83 c4 10 add $0x10,%esp + 11ae: 3d f4 01 00 00 cmp $0x1f4,%eax + 11b3: 75 4a jne 11ff + for (i = 0; i < 12; i++) { + 11b5: 83 eb 01 sub $0x1,%ebx + 11b8: 75 de jne 1198 + exit(); + 11ba: e8 14 27 00 00 call 38d3 + printf(1, "create failed\n"); + 11bf: 51 push %ecx + 11c0: 51 push %ecx + 11c1: 68 6f 44 00 00 push $0x446f + 11c6: 6a 01 push $0x1 + 11c8: e8 73 28 00 00 call 3a40 + exit(); + 11cd: e8 01 27 00 00 call 38d3 + 11d2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + printf(1, "fork failed\n"); + 11d8: 83 ec 08 sub $0x8,%esp + 11db: 68 a9 4c 00 00 push $0x4ca9 + 11e0: 6a 01 push $0x1 + 11e2: e8 59 28 00 00 call 3a40 + exit(); + 11e7: e8 e7 26 00 00 call 38d3 + printf(1, "wrong length %d\n", total); + 11ec: 50 push %eax + 11ed: 53 push %ebx + 11ee: 68 01 42 00 00 push $0x4201 + 11f3: 6a 01 push $0x1 + 11f5: e8 46 28 00 00 call 3a40 + exit(); + 11fa: e8 d4 26 00 00 call 38d3 + printf(1, "write failed %d\n", n); + 11ff: 52 push %edx + 1200: 50 push %eax + 1201: 68 e4 41 00 00 push $0x41e4 + 1206: 6a 01 push $0x1 + 1208: e8 33 28 00 00 call 3a40 + exit(); + 120d: e8 c1 26 00 00 call 38d3 + 1212: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1219: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00001220 : +void createdelete(void) { + 1220: 55 push %ebp + 1221: 89 e5 mov %esp,%ebp + 1223: 57 push %edi + 1224: 56 push %esi + 1225: 53 push %ebx + for (pi = 0; pi < 4; pi++) { + 1226: 31 db xor %ebx,%ebx +void createdelete(void) { + 1228: 83 ec 44 sub $0x44,%esp + printf(1, "createdelete test\n"); + 122b: 68 20 42 00 00 push $0x4220 + 1230: 6a 01 push $0x1 + 1232: e8 09 28 00 00 call 3a40 + 1237: 83 c4 10 add $0x10,%esp + pid = fork(); + 123a: e8 8c 26 00 00 call 38cb + if (pid < 0) { + 123f: 85 c0 test %eax,%eax + 1241: 0f 88 c3 01 00 00 js 140a + if (pid == 0) { + 1247: 0f 84 13 01 00 00 je 1360 + for (pi = 0; pi < 4; pi++) { + 124d: 83 c3 01 add $0x1,%ebx + 1250: 83 fb 04 cmp $0x4,%ebx + 1253: 75 e5 jne 123a + wait(); + 1255: e8 81 26 00 00 call 38db + for (i = 0; i < N; i++) { + 125a: 31 f6 xor %esi,%esi + 125c: 8d 7d c8 lea -0x38(%ebp),%edi + wait(); + 125f: e8 77 26 00 00 call 38db + 1264: e8 72 26 00 00 call 38db + 1269: e8 6d 26 00 00 call 38db + name[0] = name[1] = name[2] = 0; + 126e: c6 45 ca 00 movb $0x0,-0x36(%ebp) + for (i = 0; i < N; i++) { + 1272: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if ((i == 0 || i >= N / 2) && fd < 0) { + 1278: 85 f6 test %esi,%esi + 127a: 8d 46 30 lea 0x30(%esi),%eax + 127d: 0f 94 c3 sete %bl + 1280: 83 fe 09 cmp $0x9,%esi + 1283: 88 45 c7 mov %al,-0x39(%ebp) + 1286: 0f 9f c0 setg %al + 1289: 09 c3 or %eax,%ebx + else if ((i >= 1 && i < N / 2) && fd >= 0) { + 128b: 8d 46 ff lea -0x1(%esi),%eax + 128e: 89 45 c0 mov %eax,-0x40(%ebp) + if ((i == 0 || i >= N / 2) && fd < 0) { + 1291: 88 5d c6 mov %bl,-0x3a(%ebp) + 1294: bb 70 00 00 00 mov $0x70,%ebx + fd = open(name, 0); + 1299: 83 ec 08 sub $0x8,%esp + name[1] = '0' + i; + 129c: 0f b6 45 c7 movzbl -0x39(%ebp),%eax + name[0] = 'p' + pi; + 12a0: 88 5d c8 mov %bl,-0x38(%ebp) + fd = open(name, 0); + 12a3: 6a 00 push $0x0 + 12a5: 57 push %edi + name[1] = '0' + i; + 12a6: 88 45 c9 mov %al,-0x37(%ebp) + fd = open(name, 0); + 12a9: e8 8d 26 00 00 call 393b + if ((i == 0 || i >= N / 2) && fd < 0) { + 12ae: 83 c4 10 add $0x10,%esp + 12b1: 80 7d c6 00 cmpb $0x0,-0x3a(%ebp) + 12b5: 0f 84 85 00 00 00 je 1340 + 12bb: 85 c0 test %eax,%eax + 12bd: 0f 88 32 01 00 00 js 13f5 + else if ((i >= 1 && i < N / 2) && fd >= 0) { + 12c3: 83 7d c0 08 cmpl $0x8,-0x40(%ebp) + 12c7: 76 7b jbe 1344 + close(fd); + 12c9: 83 ec 0c sub $0xc,%esp + 12cc: 50 push %eax + 12cd: e8 99 26 00 00 call 396b + 12d2: 83 c4 10 add $0x10,%esp + for (pi = 0; pi < 4; pi++) { + 12d5: 83 c3 01 add $0x1,%ebx + 12d8: 80 fb 74 cmp $0x74,%bl + 12db: 75 bc jne 1299 + for (i = 0; i < N; i++) { + 12dd: 83 c6 01 add $0x1,%esi + 12e0: 83 fe 14 cmp $0x14,%esi + 12e3: 75 93 jne 1278 + 12e5: be 70 00 00 00 mov $0x70,%esi + 12ea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (pi = 0; pi < 4; pi++) { + 12f0: 8d 46 c0 lea -0x40(%esi),%eax + name[0] = 'p' + i; + 12f3: bb 04 00 00 00 mov $0x4,%ebx + 12f8: 88 45 c7 mov %al,-0x39(%ebp) + unlink(name); + 12fb: 83 ec 0c sub $0xc,%esp + name[0] = 'p' + i; + 12fe: 89 f0 mov %esi,%eax + unlink(name); + 1300: 57 push %edi + name[0] = 'p' + i; + 1301: 88 45 c8 mov %al,-0x38(%ebp) + name[1] = '0' + i; + 1304: 0f b6 45 c7 movzbl -0x39(%ebp),%eax + 1308: 88 45 c9 mov %al,-0x37(%ebp) + unlink(name); + 130b: e8 43 26 00 00 call 3953 + for (pi = 0; pi < 4; pi++) { + 1310: 83 c4 10 add $0x10,%esp + 1313: 83 eb 01 sub $0x1,%ebx + 1316: 75 e3 jne 12fb + for (i = 0; i < N; i++) { + 1318: 83 c6 01 add $0x1,%esi + 131b: 89 f0 mov %esi,%eax + 131d: 3c 84 cmp $0x84,%al + 131f: 75 cf jne 12f0 + printf(1, "createdelete ok\n"); + 1321: 83 ec 08 sub $0x8,%esp + 1324: 68 33 42 00 00 push $0x4233 + 1329: 6a 01 push $0x1 + 132b: e8 10 27 00 00 call 3a40 +} + 1330: 8d 65 f4 lea -0xc(%ebp),%esp + 1333: 5b pop %ebx + 1334: 5e pop %esi + 1335: 5f pop %edi + 1336: 5d pop %ebp + 1337: c3 ret + 1338: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 133f: 90 nop + else if ((i >= 1 && i < N / 2) && fd >= 0) { + 1340: 85 c0 test %eax,%eax + 1342: 78 91 js 12d5 + printf(1, "oops createdelete %s did exist\n", name); + 1344: 50 push %eax + 1345: 57 push %edi + 1346: 68 04 4f 00 00 push $0x4f04 + 134b: 6a 01 push $0x1 + 134d: e8 ee 26 00 00 call 3a40 + exit(); + 1352: e8 7c 25 00 00 call 38d3 + 1357: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 135e: 66 90 xchg %ax,%ax + name[0] = 'p' + pi; + 1360: 83 c3 70 add $0x70,%ebx + name[2] = '\0'; + 1363: c6 45 ca 00 movb $0x0,-0x36(%ebp) + 1367: be 01 00 00 00 mov $0x1,%esi + 136c: 8d 7d c8 lea -0x38(%ebp),%edi + name[0] = 'p' + pi; + 136f: 88 5d c8 mov %bl,-0x38(%ebp) + name[2] = '\0'; + 1372: 31 db xor %ebx,%ebx + 1374: eb 15 jmp 138b + 1376: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 137d: 8d 76 00 lea 0x0(%esi),%esi + for (i = 0; i < N; i++) { + 1380: 83 fe 14 cmp $0x14,%esi + 1383: 74 6b je 13f0 + 1385: 83 c3 01 add $0x1,%ebx + 1388: 83 c6 01 add $0x1,%esi + fd = open(name, O_CREATE | O_RDWR); + 138b: 83 ec 08 sub $0x8,%esp + name[1] = '0' + i; + 138e: 8d 43 30 lea 0x30(%ebx),%eax + fd = open(name, O_CREATE | O_RDWR); + 1391: 68 02 02 00 00 push $0x202 + 1396: 57 push %edi + name[1] = '0' + i; + 1397: 88 45 c9 mov %al,-0x37(%ebp) + fd = open(name, O_CREATE | O_RDWR); + 139a: e8 9c 25 00 00 call 393b + if (fd < 0) { + 139f: 83 c4 10 add $0x10,%esp + 13a2: 85 c0 test %eax,%eax + 13a4: 78 78 js 141e + close(fd); + 13a6: 83 ec 0c sub $0xc,%esp + 13a9: 50 push %eax + 13aa: e8 bc 25 00 00 call 396b + if (i > 0 && (i % 2) == 0) { + 13af: 83 c4 10 add $0x10,%esp + 13b2: 85 db test %ebx,%ebx + 13b4: 74 cf je 1385 + 13b6: f6 c3 01 test $0x1,%bl + 13b9: 75 c5 jne 1380 + if (unlink(name) < 0) { + 13bb: 83 ec 0c sub $0xc,%esp + name[1] = '0' + (i / 2); + 13be: 89 d8 mov %ebx,%eax + if (unlink(name) < 0) { + 13c0: 57 push %edi + name[1] = '0' + (i / 2); + 13c1: d1 f8 sar %eax + 13c3: 83 c0 30 add $0x30,%eax + 13c6: 88 45 c9 mov %al,-0x37(%ebp) + if (unlink(name) < 0) { + 13c9: e8 85 25 00 00 call 3953 + 13ce: 83 c4 10 add $0x10,%esp + 13d1: 85 c0 test %eax,%eax + 13d3: 79 ab jns 1380 + printf(1, "unlink failed\n"); + 13d5: 52 push %edx + 13d6: 52 push %edx + 13d7: 68 21 3e 00 00 push $0x3e21 + 13dc: 6a 01 push $0x1 + 13de: e8 5d 26 00 00 call 3a40 + exit(); + 13e3: e8 eb 24 00 00 call 38d3 + 13e8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 13ef: 90 nop + exit(); + 13f0: e8 de 24 00 00 call 38d3 + printf(1, "oops createdelete %s didn't exist\n", name); + 13f5: 83 ec 04 sub $0x4,%esp + 13f8: 57 push %edi + 13f9: 68 e0 4e 00 00 push $0x4ee0 + 13fe: 6a 01 push $0x1 + 1400: e8 3b 26 00 00 call 3a40 + exit(); + 1405: e8 c9 24 00 00 call 38d3 + printf(1, "fork failed\n"); + 140a: 83 ec 08 sub $0x8,%esp + 140d: 68 a9 4c 00 00 push $0x4ca9 + 1412: 6a 01 push $0x1 + 1414: e8 27 26 00 00 call 3a40 + exit(); + 1419: e8 b5 24 00 00 call 38d3 + printf(1, "create failed\n"); + 141e: 83 ec 08 sub $0x8,%esp + 1421: 68 6f 44 00 00 push $0x446f + 1426: 6a 01 push $0x1 + 1428: e8 13 26 00 00 call 3a40 + exit(); + 142d: e8 a1 24 00 00 call 38d3 + 1432: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1439: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00001440 : +void unlinkread(void) { + 1440: 55 push %ebp + 1441: 89 e5 mov %esp,%ebp + 1443: 56 push %esi + 1444: 53 push %ebx + printf(1, "unlinkread test\n"); + 1445: 83 ec 08 sub $0x8,%esp + 1448: 68 44 42 00 00 push $0x4244 + 144d: 6a 01 push $0x1 + 144f: e8 ec 25 00 00 call 3a40 + fd = open("unlinkread", O_CREATE | O_RDWR); + 1454: 5b pop %ebx + 1455: 5e pop %esi + 1456: 68 02 02 00 00 push $0x202 + 145b: 68 55 42 00 00 push $0x4255 + 1460: e8 d6 24 00 00 call 393b + if (fd < 0) { + 1465: 83 c4 10 add $0x10,%esp + 1468: 85 c0 test %eax,%eax + 146a: 0f 88 e6 00 00 00 js 1556 + write(fd, "hello", 5); + 1470: 83 ec 04 sub $0x4,%esp + 1473: 89 c3 mov %eax,%ebx + 1475: 6a 05 push $0x5 + 1477: 68 7a 42 00 00 push $0x427a + 147c: 50 push %eax + 147d: e8 c1 24 00 00 call 3943 + close(fd); + 1482: 89 1c 24 mov %ebx,(%esp) + 1485: e8 e1 24 00 00 call 396b + fd = open("unlinkread", O_RDWR); + 148a: 58 pop %eax + 148b: 5a pop %edx + 148c: 6a 02 push $0x2 + 148e: 68 55 42 00 00 push $0x4255 + 1493: e8 a3 24 00 00 call 393b + if (fd < 0) { + 1498: 83 c4 10 add $0x10,%esp + fd = open("unlinkread", O_RDWR); + 149b: 89 c3 mov %eax,%ebx + if (fd < 0) { + 149d: 85 c0 test %eax,%eax + 149f: 0f 88 10 01 00 00 js 15b5 + if (unlink("unlinkread") != 0) { + 14a5: 83 ec 0c sub $0xc,%esp + 14a8: 68 55 42 00 00 push $0x4255 + 14ad: e8 a1 24 00 00 call 3953 + 14b2: 83 c4 10 add $0x10,%esp + 14b5: 85 c0 test %eax,%eax + 14b7: 0f 85 e5 00 00 00 jne 15a2 + fd1 = open("unlinkread", O_CREATE | O_RDWR); + 14bd: 83 ec 08 sub $0x8,%esp + 14c0: 68 02 02 00 00 push $0x202 + 14c5: 68 55 42 00 00 push $0x4255 + 14ca: e8 6c 24 00 00 call 393b + write(fd1, "yyy", 3); + 14cf: 83 c4 0c add $0xc,%esp + 14d2: 6a 03 push $0x3 + fd1 = open("unlinkread", O_CREATE | O_RDWR); + 14d4: 89 c6 mov %eax,%esi + write(fd1, "yyy", 3); + 14d6: 68 b2 42 00 00 push $0x42b2 + 14db: 50 push %eax + 14dc: e8 62 24 00 00 call 3943 + close(fd1); + 14e1: 89 34 24 mov %esi,(%esp) + 14e4: e8 82 24 00 00 call 396b + if (read(fd, buf, sizeof(buf)) != 5) { + 14e9: 83 c4 0c add $0xc,%esp + 14ec: 68 00 20 00 00 push $0x2000 + 14f1: 68 a0 85 00 00 push $0x85a0 + 14f6: 53 push %ebx + 14f7: e8 ef 23 00 00 call 38eb + 14fc: 83 c4 10 add $0x10,%esp + 14ff: 83 f8 05 cmp $0x5,%eax + 1502: 0f 85 87 00 00 00 jne 158f + if (buf[0] != 'h') { + 1508: 80 3d a0 85 00 00 68 cmpb $0x68,0x85a0 + 150f: 75 6b jne 157c + if (write(fd, buf, 10) != 10) { + 1511: 83 ec 04 sub $0x4,%esp + 1514: 6a 0a push $0xa + 1516: 68 a0 85 00 00 push $0x85a0 + 151b: 53 push %ebx + 151c: e8 22 24 00 00 call 3943 + 1521: 83 c4 10 add $0x10,%esp + 1524: 83 f8 0a cmp $0xa,%eax + 1527: 75 40 jne 1569 + close(fd); + 1529: 83 ec 0c sub $0xc,%esp + 152c: 53 push %ebx + 152d: e8 39 24 00 00 call 396b + unlink("unlinkread"); + 1532: c7 04 24 55 42 00 00 movl $0x4255,(%esp) + 1539: e8 15 24 00 00 call 3953 + printf(1, "unlinkread ok\n"); + 153e: 58 pop %eax + 153f: 5a pop %edx + 1540: 68 fd 42 00 00 push $0x42fd + 1545: 6a 01 push $0x1 + 1547: e8 f4 24 00 00 call 3a40 +} + 154c: 83 c4 10 add $0x10,%esp + 154f: 8d 65 f8 lea -0x8(%ebp),%esp + 1552: 5b pop %ebx + 1553: 5e pop %esi + 1554: 5d pop %ebp + 1555: c3 ret + printf(1, "create unlinkread failed\n"); + 1556: 51 push %ecx + 1557: 51 push %ecx + 1558: 68 60 42 00 00 push $0x4260 + 155d: 6a 01 push $0x1 + 155f: e8 dc 24 00 00 call 3a40 + exit(); + 1564: e8 6a 23 00 00 call 38d3 + printf(1, "unlinkread write failed\n"); + 1569: 51 push %ecx + 156a: 51 push %ecx + 156b: 68 e4 42 00 00 push $0x42e4 + 1570: 6a 01 push $0x1 + 1572: e8 c9 24 00 00 call 3a40 + exit(); + 1577: e8 57 23 00 00 call 38d3 + printf(1, "unlinkread wrong data\n"); + 157c: 53 push %ebx + 157d: 53 push %ebx + 157e: 68 cd 42 00 00 push $0x42cd + 1583: 6a 01 push $0x1 + 1585: e8 b6 24 00 00 call 3a40 + exit(); + 158a: e8 44 23 00 00 call 38d3 + printf(1, "unlinkread read failed"); + 158f: 56 push %esi + 1590: 56 push %esi + 1591: 68 b6 42 00 00 push $0x42b6 + 1596: 6a 01 push $0x1 + 1598: e8 a3 24 00 00 call 3a40 + exit(); + 159d: e8 31 23 00 00 call 38d3 + printf(1, "unlink unlinkread failed\n"); + 15a2: 50 push %eax + 15a3: 50 push %eax + 15a4: 68 98 42 00 00 push $0x4298 + 15a9: 6a 01 push $0x1 + 15ab: e8 90 24 00 00 call 3a40 + exit(); + 15b0: e8 1e 23 00 00 call 38d3 + printf(1, "open unlinkread failed\n"); + 15b5: 50 push %eax + 15b6: 50 push %eax + 15b7: 68 80 42 00 00 push $0x4280 + 15bc: 6a 01 push $0x1 + 15be: e8 7d 24 00 00 call 3a40 + exit(); + 15c3: e8 0b 23 00 00 call 38d3 + 15c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 15cf: 90 nop + +000015d0 : +void linktest(void) { + 15d0: 55 push %ebp + 15d1: 89 e5 mov %esp,%ebp + 15d3: 53 push %ebx + 15d4: 83 ec 0c sub $0xc,%esp + printf(1, "linktest\n"); + 15d7: 68 0c 43 00 00 push $0x430c + 15dc: 6a 01 push $0x1 + 15de: e8 5d 24 00 00 call 3a40 + unlink("lf1"); + 15e3: c7 04 24 16 43 00 00 movl $0x4316,(%esp) + 15ea: e8 64 23 00 00 call 3953 + unlink("lf2"); + 15ef: c7 04 24 1a 43 00 00 movl $0x431a,(%esp) + 15f6: e8 58 23 00 00 call 3953 + fd = open("lf1", O_CREATE | O_RDWR); + 15fb: 58 pop %eax + 15fc: 5a pop %edx + 15fd: 68 02 02 00 00 push $0x202 + 1602: 68 16 43 00 00 push $0x4316 + 1607: e8 2f 23 00 00 call 393b + if (fd < 0) { + 160c: 83 c4 10 add $0x10,%esp + 160f: 85 c0 test %eax,%eax + 1611: 0f 88 1e 01 00 00 js 1735 + if (write(fd, "hello", 5) != 5) { + 1617: 83 ec 04 sub $0x4,%esp + 161a: 89 c3 mov %eax,%ebx + 161c: 6a 05 push $0x5 + 161e: 68 7a 42 00 00 push $0x427a + 1623: 50 push %eax + 1624: e8 1a 23 00 00 call 3943 + 1629: 83 c4 10 add $0x10,%esp + 162c: 83 f8 05 cmp $0x5,%eax + 162f: 0f 85 98 01 00 00 jne 17cd + close(fd); + 1635: 83 ec 0c sub $0xc,%esp + 1638: 53 push %ebx + 1639: e8 2d 23 00 00 call 396b + if (link("lf1", "lf2") < 0) { + 163e: 5b pop %ebx + 163f: 58 pop %eax + 1640: 68 1a 43 00 00 push $0x431a + 1645: 68 16 43 00 00 push $0x4316 + 164a: e8 0c 23 00 00 call 395b + 164f: 83 c4 10 add $0x10,%esp + 1652: 85 c0 test %eax,%eax + 1654: 0f 88 60 01 00 00 js 17ba + unlink("lf1"); + 165a: 83 ec 0c sub $0xc,%esp + 165d: 68 16 43 00 00 push $0x4316 + 1662: e8 ec 22 00 00 call 3953 + if (open("lf1", 0) >= 0) { + 1667: 58 pop %eax + 1668: 5a pop %edx + 1669: 6a 00 push $0x0 + 166b: 68 16 43 00 00 push $0x4316 + 1670: e8 c6 22 00 00 call 393b + 1675: 83 c4 10 add $0x10,%esp + 1678: 85 c0 test %eax,%eax + 167a: 0f 89 27 01 00 00 jns 17a7 + fd = open("lf2", 0); + 1680: 83 ec 08 sub $0x8,%esp + 1683: 6a 00 push $0x0 + 1685: 68 1a 43 00 00 push $0x431a + 168a: e8 ac 22 00 00 call 393b + if (fd < 0) { + 168f: 83 c4 10 add $0x10,%esp + fd = open("lf2", 0); + 1692: 89 c3 mov %eax,%ebx + if (fd < 0) { + 1694: 85 c0 test %eax,%eax + 1696: 0f 88 f8 00 00 00 js 1794 + if (read(fd, buf, sizeof(buf)) != 5) { + 169c: 83 ec 04 sub $0x4,%esp + 169f: 68 00 20 00 00 push $0x2000 + 16a4: 68 a0 85 00 00 push $0x85a0 + 16a9: 50 push %eax + 16aa: e8 3c 22 00 00 call 38eb + 16af: 83 c4 10 add $0x10,%esp + 16b2: 83 f8 05 cmp $0x5,%eax + 16b5: 0f 85 c6 00 00 00 jne 1781 + close(fd); + 16bb: 83 ec 0c sub $0xc,%esp + 16be: 53 push %ebx + 16bf: e8 a7 22 00 00 call 396b + if (link("lf2", "lf2") >= 0) { + 16c4: 58 pop %eax + 16c5: 5a pop %edx + 16c6: 68 1a 43 00 00 push $0x431a + 16cb: 68 1a 43 00 00 push $0x431a + 16d0: e8 86 22 00 00 call 395b + 16d5: 83 c4 10 add $0x10,%esp + 16d8: 85 c0 test %eax,%eax + 16da: 0f 89 8e 00 00 00 jns 176e + unlink("lf2"); + 16e0: 83 ec 0c sub $0xc,%esp + 16e3: 68 1a 43 00 00 push $0x431a + 16e8: e8 66 22 00 00 call 3953 + if (link("lf2", "lf1") >= 0) { + 16ed: 59 pop %ecx + 16ee: 5b pop %ebx + 16ef: 68 16 43 00 00 push $0x4316 + 16f4: 68 1a 43 00 00 push $0x431a + 16f9: e8 5d 22 00 00 call 395b + 16fe: 83 c4 10 add $0x10,%esp + 1701: 85 c0 test %eax,%eax + 1703: 79 56 jns 175b + if (link(".", "lf1") >= 0) { + 1705: 83 ec 08 sub $0x8,%esp + 1708: 68 16 43 00 00 push $0x4316 + 170d: 68 de 45 00 00 push $0x45de + 1712: e8 44 22 00 00 call 395b + 1717: 83 c4 10 add $0x10,%esp + 171a: 85 c0 test %eax,%eax + 171c: 79 2a jns 1748 + printf(1, "linktest ok\n"); + 171e: 83 ec 08 sub $0x8,%esp + 1721: 68 b4 43 00 00 push $0x43b4 + 1726: 6a 01 push $0x1 + 1728: e8 13 23 00 00 call 3a40 +} + 172d: 8b 5d fc mov -0x4(%ebp),%ebx + 1730: 83 c4 10 add $0x10,%esp + 1733: c9 leave + 1734: c3 ret + printf(1, "create lf1 failed\n"); + 1735: 50 push %eax + 1736: 50 push %eax + 1737: 68 1e 43 00 00 push $0x431e + 173c: 6a 01 push $0x1 + 173e: e8 fd 22 00 00 call 3a40 + exit(); + 1743: e8 8b 21 00 00 call 38d3 + printf(1, "link . lf1 succeeded! oops\n"); + 1748: 50 push %eax + 1749: 50 push %eax + 174a: 68 98 43 00 00 push $0x4398 + 174f: 6a 01 push $0x1 + 1751: e8 ea 22 00 00 call 3a40 + exit(); + 1756: e8 78 21 00 00 call 38d3 + printf(1, "link non-existant succeeded! oops\n"); + 175b: 52 push %edx + 175c: 52 push %edx + 175d: 68 4c 4f 00 00 push $0x4f4c + 1762: 6a 01 push $0x1 + 1764: e8 d7 22 00 00 call 3a40 + exit(); + 1769: e8 65 21 00 00 call 38d3 + printf(1, "link lf2 lf2 succeeded! oops\n"); + 176e: 50 push %eax + 176f: 50 push %eax + 1770: 68 7a 43 00 00 push $0x437a + 1775: 6a 01 push $0x1 + 1777: e8 c4 22 00 00 call 3a40 + exit(); + 177c: e8 52 21 00 00 call 38d3 + printf(1, "read lf2 failed\n"); + 1781: 51 push %ecx + 1782: 51 push %ecx + 1783: 68 69 43 00 00 push $0x4369 + 1788: 6a 01 push $0x1 + 178a: e8 b1 22 00 00 call 3a40 + exit(); + 178f: e8 3f 21 00 00 call 38d3 + printf(1, "open lf2 failed\n"); + 1794: 53 push %ebx + 1795: 53 push %ebx + 1796: 68 58 43 00 00 push $0x4358 + 179b: 6a 01 push $0x1 + 179d: e8 9e 22 00 00 call 3a40 + exit(); + 17a2: e8 2c 21 00 00 call 38d3 + printf(1, "unlinked lf1 but it is still there!\n"); + 17a7: 50 push %eax + 17a8: 50 push %eax + 17a9: 68 24 4f 00 00 push $0x4f24 + 17ae: 6a 01 push $0x1 + 17b0: e8 8b 22 00 00 call 3a40 + exit(); + 17b5: e8 19 21 00 00 call 38d3 + printf(1, "link lf1 lf2 failed\n"); + 17ba: 51 push %ecx + 17bb: 51 push %ecx + 17bc: 68 43 43 00 00 push $0x4343 + 17c1: 6a 01 push $0x1 + 17c3: e8 78 22 00 00 call 3a40 + exit(); + 17c8: e8 06 21 00 00 call 38d3 + printf(1, "write lf1 failed\n"); + 17cd: 50 push %eax + 17ce: 50 push %eax + 17cf: 68 31 43 00 00 push $0x4331 + 17d4: 6a 01 push $0x1 + 17d6: e8 65 22 00 00 call 3a40 + exit(); + 17db: e8 f3 20 00 00 call 38d3 + +000017e0 : +void concreate(void) { + 17e0: 55 push %ebp + 17e1: 89 e5 mov %esp,%ebp + 17e3: 57 push %edi + 17e4: 56 push %esi + for (i = 0; i < 40; i++) { + 17e5: 31 f6 xor %esi,%esi +void concreate(void) { + 17e7: 53 push %ebx + 17e8: 8d 5d ad lea -0x53(%ebp),%ebx + 17eb: 83 ec 64 sub $0x64,%esp + printf(1, "concreate test\n"); + 17ee: 68 c1 43 00 00 push $0x43c1 + 17f3: 6a 01 push $0x1 + 17f5: e8 46 22 00 00 call 3a40 + file[0] = 'C'; + 17fa: c6 45 ad 43 movb $0x43,-0x53(%ebp) + file[2] = '\0'; + 17fe: 83 c4 10 add $0x10,%esp + 1801: c6 45 af 00 movb $0x0,-0x51(%ebp) + for (i = 0; i < 40; i++) { + 1805: eb 4c jmp 1853 + 1807: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 180e: 66 90 xchg %ax,%ax + 1810: 69 c6 ab aa aa aa imul $0xaaaaaaab,%esi,%eax + if (pid && (i % 3) == 1) { + 1816: 3d ab aa aa aa cmp $0xaaaaaaab,%eax + 181b: 0f 83 af 00 00 00 jae 18d0 + fd = open(file, O_CREATE | O_RDWR); + 1821: 83 ec 08 sub $0x8,%esp + 1824: 68 02 02 00 00 push $0x202 + 1829: 53 push %ebx + 182a: e8 0c 21 00 00 call 393b + if (fd < 0) { + 182f: 83 c4 10 add $0x10,%esp + 1832: 85 c0 test %eax,%eax + 1834: 78 5f js 1895 + close(fd); + 1836: 83 ec 0c sub $0xc,%esp + for (i = 0; i < 40; i++) { + 1839: 83 c6 01 add $0x1,%esi + close(fd); + 183c: 50 push %eax + 183d: e8 29 21 00 00 call 396b + 1842: 83 c4 10 add $0x10,%esp + wait(); + 1845: e8 91 20 00 00 call 38db + for (i = 0; i < 40; i++) { + 184a: 83 fe 28 cmp $0x28,%esi + 184d: 0f 84 9f 00 00 00 je 18f2 + unlink(file); + 1853: 83 ec 0c sub $0xc,%esp + file[1] = '0' + i; + 1856: 8d 46 30 lea 0x30(%esi),%eax + unlink(file); + 1859: 53 push %ebx + file[1] = '0' + i; + 185a: 88 45 ae mov %al,-0x52(%ebp) + unlink(file); + 185d: e8 f1 20 00 00 call 3953 + pid = fork(); + 1862: e8 64 20 00 00 call 38cb + if (pid && (i % 3) == 1) { + 1867: 83 c4 10 add $0x10,%esp + 186a: 85 c0 test %eax,%eax + 186c: 75 a2 jne 1810 + link("C0", file); + 186e: 69 f6 cd cc cc cc imul $0xcccccccd,%esi,%esi + else if (pid == 0 && (i % 5) == 1) { + 1874: 81 fe cd cc cc cc cmp $0xcccccccd,%esi + 187a: 73 34 jae 18b0 + fd = open(file, O_CREATE | O_RDWR); + 187c: 83 ec 08 sub $0x8,%esp + 187f: 68 02 02 00 00 push $0x202 + 1884: 53 push %ebx + 1885: e8 b1 20 00 00 call 393b + if (fd < 0) { + 188a: 83 c4 10 add $0x10,%esp + 188d: 85 c0 test %eax,%eax + 188f: 0f 89 39 02 00 00 jns 1ace + printf(1, "concreate create %s failed\n", file); + 1895: 83 ec 04 sub $0x4,%esp + 1898: 53 push %ebx + 1899: 68 d4 43 00 00 push $0x43d4 + 189e: 6a 01 push $0x1 + 18a0: e8 9b 21 00 00 call 3a40 + exit(); + 18a5: e8 29 20 00 00 call 38d3 + 18aa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + link("C0", file); + 18b0: 83 ec 08 sub $0x8,%esp + 18b3: 53 push %ebx + 18b4: 68 d1 43 00 00 push $0x43d1 + 18b9: e8 9d 20 00 00 call 395b + 18be: 83 c4 10 add $0x10,%esp + exit(); + 18c1: e8 0d 20 00 00 call 38d3 + 18c6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 18cd: 8d 76 00 lea 0x0(%esi),%esi + link("C0", file); + 18d0: 83 ec 08 sub $0x8,%esp + for (i = 0; i < 40; i++) { + 18d3: 83 c6 01 add $0x1,%esi + link("C0", file); + 18d6: 53 push %ebx + 18d7: 68 d1 43 00 00 push $0x43d1 + 18dc: e8 7a 20 00 00 call 395b + 18e1: 83 c4 10 add $0x10,%esp + wait(); + 18e4: e8 f2 1f 00 00 call 38db + for (i = 0; i < 40; i++) { + 18e9: 83 fe 28 cmp $0x28,%esi + 18ec: 0f 85 61 ff ff ff jne 1853 + memset(fa, 0, sizeof(fa)); + 18f2: 83 ec 04 sub $0x4,%esp + 18f5: 8d 45 c0 lea -0x40(%ebp),%eax + 18f8: 6a 28 push $0x28 + 18fa: 6a 00 push $0x0 + 18fc: 50 push %eax + 18fd: e8 3e 1e 00 00 call 3740 + fd = open(".", 0); + 1902: 5e pop %esi + 1903: 5f pop %edi + 1904: 6a 00 push $0x0 + 1906: 68 de 45 00 00 push $0x45de + 190b: 8d 7d b0 lea -0x50(%ebp),%edi + 190e: e8 28 20 00 00 call 393b + n = 0; + 1913: c7 45 a4 00 00 00 00 movl $0x0,-0x5c(%ebp) + while (read(fd, &de, sizeof(de)) > 0) { + 191a: 83 c4 10 add $0x10,%esp + fd = open(".", 0); + 191d: 89 c6 mov %eax,%esi + while (read(fd, &de, sizeof(de)) > 0) { + 191f: 90 nop + 1920: 83 ec 04 sub $0x4,%esp + 1923: 6a 10 push $0x10 + 1925: 57 push %edi + 1926: 56 push %esi + 1927: e8 bf 1f 00 00 call 38eb + 192c: 83 c4 10 add $0x10,%esp + 192f: 85 c0 test %eax,%eax + 1931: 7e 3d jle 1970 + if (de.inum == 0) { + 1933: 66 83 7d b0 00 cmpw $0x0,-0x50(%ebp) + 1938: 74 e6 je 1920 + if (de.name[0] == 'C' && de.name[2] == '\0') { + 193a: 80 7d b2 43 cmpb $0x43,-0x4e(%ebp) + 193e: 75 e0 jne 1920 + 1940: 80 7d b4 00 cmpb $0x0,-0x4c(%ebp) + 1944: 75 da jne 1920 + i = de.name[1] - '0'; + 1946: 0f be 45 b3 movsbl -0x4d(%ebp),%eax + 194a: 83 e8 30 sub $0x30,%eax + if (i < 0 || i >= sizeof(fa)) { + 194d: 83 f8 27 cmp $0x27,%eax + 1950: 0f 87 60 01 00 00 ja 1ab6 + if (fa[i]) { + 1956: 80 7c 05 c0 00 cmpb $0x0,-0x40(%ebp,%eax,1) + 195b: 0f 85 3d 01 00 00 jne 1a9e + n++; + 1961: 83 45 a4 01 addl $0x1,-0x5c(%ebp) + fa[i] = 1; + 1965: c6 44 05 c0 01 movb $0x1,-0x40(%ebp,%eax,1) + n++; + 196a: eb b4 jmp 1920 + 196c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + close(fd); + 1970: 83 ec 0c sub $0xc,%esp + 1973: 56 push %esi + 1974: e8 f2 1f 00 00 call 396b + if (n != 40) { + 1979: 83 c4 10 add $0x10,%esp + 197c: 83 7d a4 28 cmpl $0x28,-0x5c(%ebp) + 1980: 0f 85 05 01 00 00 jne 1a8b + for (i = 0; i < 40; i++) { + 1986: 31 f6 xor %esi,%esi + 1988: eb 4c jmp 19d6 + 198a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + ((i % 3) == 1 && pid != 0)) { + 1990: 85 ff test %edi,%edi + 1992: 74 05 je 1999 + 1994: 83 f8 01 cmp $0x1,%eax + 1997: 74 6c je 1a05 + unlink(file); + 1999: 83 ec 0c sub $0xc,%esp + 199c: 53 push %ebx + 199d: e8 b1 1f 00 00 call 3953 + unlink(file); + 19a2: 89 1c 24 mov %ebx,(%esp) + 19a5: e8 a9 1f 00 00 call 3953 + unlink(file); + 19aa: 89 1c 24 mov %ebx,(%esp) + 19ad: e8 a1 1f 00 00 call 3953 + unlink(file); + 19b2: 89 1c 24 mov %ebx,(%esp) + 19b5: e8 99 1f 00 00 call 3953 + 19ba: 83 c4 10 add $0x10,%esp + if (pid == 0) { + 19bd: 85 ff test %edi,%edi + 19bf: 0f 84 fc fe ff ff je 18c1 + wait(); + 19c5: e8 11 1f 00 00 call 38db + for (i = 0; i < 40; i++) { + 19ca: 83 c6 01 add $0x1,%esi + 19cd: 83 fe 28 cmp $0x28,%esi + 19d0: 0f 84 8a 00 00 00 je 1a60 + file[1] = '0' + i; + 19d6: 8d 46 30 lea 0x30(%esi),%eax + 19d9: 88 45 ae mov %al,-0x52(%ebp) + pid = fork(); + 19dc: e8 ea 1e 00 00 call 38cb + 19e1: 89 c7 mov %eax,%edi + if (pid < 0) { + 19e3: 85 c0 test %eax,%eax + 19e5: 0f 88 8c 00 00 00 js 1a77 + if (((i % 3) == 0 && pid == 0) || + 19eb: b8 ab aa aa aa mov $0xaaaaaaab,%eax + 19f0: f7 e6 mul %esi + 19f2: 89 d0 mov %edx,%eax + 19f4: 83 e2 fe and $0xfffffffe,%edx + 19f7: d1 e8 shr %eax + 19f9: 01 c2 add %eax,%edx + 19fb: 89 f0 mov %esi,%eax + 19fd: 29 d0 sub %edx,%eax + 19ff: 89 c1 mov %eax,%ecx + 1a01: 09 f9 or %edi,%ecx + 1a03: 75 8b jne 1990 + close(open(file, 0)); + 1a05: 83 ec 08 sub $0x8,%esp + 1a08: 6a 00 push $0x0 + 1a0a: 53 push %ebx + 1a0b: e8 2b 1f 00 00 call 393b + 1a10: 89 04 24 mov %eax,(%esp) + 1a13: e8 53 1f 00 00 call 396b + close(open(file, 0)); + 1a18: 58 pop %eax + 1a19: 5a pop %edx + 1a1a: 6a 00 push $0x0 + 1a1c: 53 push %ebx + 1a1d: e8 19 1f 00 00 call 393b + 1a22: 89 04 24 mov %eax,(%esp) + 1a25: e8 41 1f 00 00 call 396b + close(open(file, 0)); + 1a2a: 59 pop %ecx + 1a2b: 58 pop %eax + 1a2c: 6a 00 push $0x0 + 1a2e: 53 push %ebx + 1a2f: e8 07 1f 00 00 call 393b + 1a34: 89 04 24 mov %eax,(%esp) + 1a37: e8 2f 1f 00 00 call 396b + close(open(file, 0)); + 1a3c: 58 pop %eax + 1a3d: 5a pop %edx + 1a3e: 6a 00 push $0x0 + 1a40: 53 push %ebx + 1a41: e8 f5 1e 00 00 call 393b + 1a46: 89 04 24 mov %eax,(%esp) + 1a49: e8 1d 1f 00 00 call 396b + 1a4e: 83 c4 10 add $0x10,%esp + 1a51: e9 67 ff ff ff jmp 19bd + 1a56: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1a5d: 8d 76 00 lea 0x0(%esi),%esi + printf(1, "concreate ok\n"); + 1a60: 83 ec 08 sub $0x8,%esp + 1a63: 68 26 44 00 00 push $0x4426 + 1a68: 6a 01 push $0x1 + 1a6a: e8 d1 1f 00 00 call 3a40 +} + 1a6f: 8d 65 f4 lea -0xc(%ebp),%esp + 1a72: 5b pop %ebx + 1a73: 5e pop %esi + 1a74: 5f pop %edi + 1a75: 5d pop %ebp + 1a76: c3 ret + printf(1, "fork failed\n"); + 1a77: 83 ec 08 sub $0x8,%esp + 1a7a: 68 a9 4c 00 00 push $0x4ca9 + 1a7f: 6a 01 push $0x1 + 1a81: e8 ba 1f 00 00 call 3a40 + exit(); + 1a86: e8 48 1e 00 00 call 38d3 + printf(1, "concreate not enough files in directory listing\n"); + 1a8b: 51 push %ecx + 1a8c: 51 push %ecx + 1a8d: 68 70 4f 00 00 push $0x4f70 + 1a92: 6a 01 push $0x1 + 1a94: e8 a7 1f 00 00 call 3a40 + exit(); + 1a99: e8 35 1e 00 00 call 38d3 + printf(1, "concreate duplicate file %s\n", de.name); + 1a9e: 83 ec 04 sub $0x4,%esp + 1aa1: 8d 45 b2 lea -0x4e(%ebp),%eax + 1aa4: 50 push %eax + 1aa5: 68 09 44 00 00 push $0x4409 + 1aaa: 6a 01 push $0x1 + 1aac: e8 8f 1f 00 00 call 3a40 + exit(); + 1ab1: e8 1d 1e 00 00 call 38d3 + printf(1, "concreate weird file %s\n", de.name); + 1ab6: 83 ec 04 sub $0x4,%esp + 1ab9: 8d 45 b2 lea -0x4e(%ebp),%eax + 1abc: 50 push %eax + 1abd: 68 f0 43 00 00 push $0x43f0 + 1ac2: 6a 01 push $0x1 + 1ac4: e8 77 1f 00 00 call 3a40 + exit(); + 1ac9: e8 05 1e 00 00 call 38d3 + close(fd); + 1ace: 83 ec 0c sub $0xc,%esp + 1ad1: 50 push %eax + 1ad2: e8 94 1e 00 00 call 396b + 1ad7: 83 c4 10 add $0x10,%esp + 1ada: e9 e2 fd ff ff jmp 18c1 + 1adf: 90 nop + +00001ae0 : +void linkunlink() { + 1ae0: 55 push %ebp + 1ae1: 89 e5 mov %esp,%ebp + 1ae3: 57 push %edi + 1ae4: 56 push %esi + 1ae5: 53 push %ebx + 1ae6: 83 ec 24 sub $0x24,%esp + printf(1, "linkunlink test\n"); + 1ae9: 68 34 44 00 00 push $0x4434 + 1aee: 6a 01 push $0x1 + 1af0: e8 4b 1f 00 00 call 3a40 + unlink("x"); + 1af5: c7 04 24 c1 46 00 00 movl $0x46c1,(%esp) + 1afc: e8 52 1e 00 00 call 3953 + pid = fork(); + 1b01: e8 c5 1d 00 00 call 38cb + if (pid < 0) { + 1b06: 83 c4 10 add $0x10,%esp + pid = fork(); + 1b09: 89 45 e4 mov %eax,-0x1c(%ebp) + if (pid < 0) { + 1b0c: 85 c0 test %eax,%eax + 1b0e: 0f 88 b6 00 00 00 js 1bca + unsigned int x = (pid ? 1 : 97); + 1b14: 83 7d e4 01 cmpl $0x1,-0x1c(%ebp) + 1b18: bb 64 00 00 00 mov $0x64,%ebx + if ((x % 3) == 0) { + 1b1d: be ab aa aa aa mov $0xaaaaaaab,%esi + unsigned int x = (pid ? 1 : 97); + 1b22: 19 ff sbb %edi,%edi + 1b24: 83 e7 60 and $0x60,%edi + 1b27: 83 c7 01 add $0x1,%edi + 1b2a: eb 1e jmp 1b4a + 1b2c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + else if ((x % 3) == 1) { + 1b30: 83 f8 01 cmp $0x1,%eax + 1b33: 74 7b je 1bb0 + unlink("x"); + 1b35: 83 ec 0c sub $0xc,%esp + 1b38: 68 c1 46 00 00 push $0x46c1 + 1b3d: e8 11 1e 00 00 call 3953 + 1b42: 83 c4 10 add $0x10,%esp + for (i = 0; i < 100; i++) { + 1b45: 83 eb 01 sub $0x1,%ebx + 1b48: 74 41 je 1b8b + x = x * 1103515245 + 12345; + 1b4a: 69 cf 6d 4e c6 41 imul $0x41c64e6d,%edi,%ecx + 1b50: 8d b9 39 30 00 00 lea 0x3039(%ecx),%edi + if ((x % 3) == 0) { + 1b56: 89 f8 mov %edi,%eax + 1b58: f7 e6 mul %esi + 1b5a: 89 d0 mov %edx,%eax + 1b5c: 83 e2 fe and $0xfffffffe,%edx + 1b5f: d1 e8 shr %eax + 1b61: 01 c2 add %eax,%edx + 1b63: 89 f8 mov %edi,%eax + 1b65: 29 d0 sub %edx,%eax + 1b67: 75 c7 jne 1b30 + close(open("x", O_RDWR | O_CREATE)); + 1b69: 83 ec 08 sub $0x8,%esp + 1b6c: 68 02 02 00 00 push $0x202 + 1b71: 68 c1 46 00 00 push $0x46c1 + 1b76: e8 c0 1d 00 00 call 393b + 1b7b: 89 04 24 mov %eax,(%esp) + 1b7e: e8 e8 1d 00 00 call 396b + 1b83: 83 c4 10 add $0x10,%esp + for (i = 0; i < 100; i++) { + 1b86: 83 eb 01 sub $0x1,%ebx + 1b89: 75 bf jne 1b4a + if (pid) { + 1b8b: 8b 45 e4 mov -0x1c(%ebp),%eax + 1b8e: 85 c0 test %eax,%eax + 1b90: 74 4b je 1bdd + wait(); + 1b92: e8 44 1d 00 00 call 38db + printf(1, "linkunlink ok\n"); + 1b97: 83 ec 08 sub $0x8,%esp + 1b9a: 68 49 44 00 00 push $0x4449 + 1b9f: 6a 01 push $0x1 + 1ba1: e8 9a 1e 00 00 call 3a40 +} + 1ba6: 8d 65 f4 lea -0xc(%ebp),%esp + 1ba9: 5b pop %ebx + 1baa: 5e pop %esi + 1bab: 5f pop %edi + 1bac: 5d pop %ebp + 1bad: c3 ret + 1bae: 66 90 xchg %ax,%ax + link("cat", "x"); + 1bb0: 83 ec 08 sub $0x8,%esp + 1bb3: 68 c1 46 00 00 push $0x46c1 + 1bb8: 68 45 44 00 00 push $0x4445 + 1bbd: e8 99 1d 00 00 call 395b + 1bc2: 83 c4 10 add $0x10,%esp + 1bc5: e9 7b ff ff ff jmp 1b45 + printf(1, "fork failed\n"); + 1bca: 52 push %edx + 1bcb: 52 push %edx + 1bcc: 68 a9 4c 00 00 push $0x4ca9 + 1bd1: 6a 01 push $0x1 + 1bd3: e8 68 1e 00 00 call 3a40 + exit(); + 1bd8: e8 f6 1c 00 00 call 38d3 + exit(); + 1bdd: e8 f1 1c 00 00 call 38d3 + 1be2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1be9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00001bf0 : +void bigdir(void) { + 1bf0: 55 push %ebp + 1bf1: 89 e5 mov %esp,%ebp + 1bf3: 57 push %edi + 1bf4: 56 push %esi + 1bf5: 53 push %ebx + 1bf6: 83 ec 24 sub $0x24,%esp + printf(1, "bigdir test\n"); + 1bf9: 68 58 44 00 00 push $0x4458 + 1bfe: 6a 01 push $0x1 + 1c00: e8 3b 1e 00 00 call 3a40 + unlink("bd"); + 1c05: c7 04 24 65 44 00 00 movl $0x4465,(%esp) + 1c0c: e8 42 1d 00 00 call 3953 + fd = open("bd", O_CREATE); + 1c11: 5a pop %edx + 1c12: 59 pop %ecx + 1c13: 68 00 02 00 00 push $0x200 + 1c18: 68 65 44 00 00 push $0x4465 + 1c1d: e8 19 1d 00 00 call 393b + if (fd < 0) { + 1c22: 83 c4 10 add $0x10,%esp + 1c25: 85 c0 test %eax,%eax + 1c27: 0f 88 de 00 00 00 js 1d0b + close(fd); + 1c2d: 83 ec 0c sub $0xc,%esp + for (i = 0; i < 500; i++) { + 1c30: 31 f6 xor %esi,%esi + 1c32: 8d 7d de lea -0x22(%ebp),%edi + close(fd); + 1c35: 50 push %eax + 1c36: e8 30 1d 00 00 call 396b + 1c3b: 83 c4 10 add $0x10,%esp + 1c3e: 66 90 xchg %ax,%ax + name[1] = '0' + (i / 64); + 1c40: 89 f0 mov %esi,%eax + if (link("bd", name) != 0) { + 1c42: 83 ec 08 sub $0x8,%esp + name[0] = 'x'; + 1c45: c6 45 de 78 movb $0x78,-0x22(%ebp) + name[1] = '0' + (i / 64); + 1c49: c1 f8 06 sar $0x6,%eax + if (link("bd", name) != 0) { + 1c4c: 57 push %edi + name[1] = '0' + (i / 64); + 1c4d: 83 c0 30 add $0x30,%eax + if (link("bd", name) != 0) { + 1c50: 68 65 44 00 00 push $0x4465 + name[1] = '0' + (i / 64); + 1c55: 88 45 df mov %al,-0x21(%ebp) + name[2] = '0' + (i % 64); + 1c58: 89 f0 mov %esi,%eax + 1c5a: 83 e0 3f and $0x3f,%eax + name[3] = '\0'; + 1c5d: c6 45 e1 00 movb $0x0,-0x1f(%ebp) + name[2] = '0' + (i % 64); + 1c61: 83 c0 30 add $0x30,%eax + 1c64: 88 45 e0 mov %al,-0x20(%ebp) + if (link("bd", name) != 0) { + 1c67: e8 ef 1c 00 00 call 395b + 1c6c: 83 c4 10 add $0x10,%esp + 1c6f: 89 c3 mov %eax,%ebx + 1c71: 85 c0 test %eax,%eax + 1c73: 75 6e jne 1ce3 + for (i = 0; i < 500; i++) { + 1c75: 83 c6 01 add $0x1,%esi + 1c78: 81 fe f4 01 00 00 cmp $0x1f4,%esi + 1c7e: 75 c0 jne 1c40 + unlink("bd"); + 1c80: 83 ec 0c sub $0xc,%esp + 1c83: 68 65 44 00 00 push $0x4465 + 1c88: e8 c6 1c 00 00 call 3953 + 1c8d: 83 c4 10 add $0x10,%esp + name[1] = '0' + (i / 64); + 1c90: 89 d8 mov %ebx,%eax + if (unlink(name) != 0) { + 1c92: 83 ec 0c sub $0xc,%esp + name[0] = 'x'; + 1c95: c6 45 de 78 movb $0x78,-0x22(%ebp) + name[1] = '0' + (i / 64); + 1c99: c1 f8 06 sar $0x6,%eax + if (unlink(name) != 0) { + 1c9c: 57 push %edi + name[1] = '0' + (i / 64); + 1c9d: 83 c0 30 add $0x30,%eax + name[3] = '\0'; + 1ca0: c6 45 e1 00 movb $0x0,-0x1f(%ebp) + name[1] = '0' + (i / 64); + 1ca4: 88 45 df mov %al,-0x21(%ebp) + name[2] = '0' + (i % 64); + 1ca7: 89 d8 mov %ebx,%eax + 1ca9: 83 e0 3f and $0x3f,%eax + 1cac: 83 c0 30 add $0x30,%eax + 1caf: 88 45 e0 mov %al,-0x20(%ebp) + if (unlink(name) != 0) { + 1cb2: e8 9c 1c 00 00 call 3953 + 1cb7: 83 c4 10 add $0x10,%esp + 1cba: 85 c0 test %eax,%eax + 1cbc: 75 39 jne 1cf7 + for (i = 0; i < 500; i++) { + 1cbe: 83 c3 01 add $0x1,%ebx + 1cc1: 81 fb f4 01 00 00 cmp $0x1f4,%ebx + 1cc7: 75 c7 jne 1c90 + printf(1, "bigdir ok\n"); + 1cc9: 83 ec 08 sub $0x8,%esp + 1ccc: 68 a7 44 00 00 push $0x44a7 + 1cd1: 6a 01 push $0x1 + 1cd3: e8 68 1d 00 00 call 3a40 + 1cd8: 83 c4 10 add $0x10,%esp +} + 1cdb: 8d 65 f4 lea -0xc(%ebp),%esp + 1cde: 5b pop %ebx + 1cdf: 5e pop %esi + 1ce0: 5f pop %edi + 1ce1: 5d pop %ebp + 1ce2: c3 ret + printf(1, "bigdir link failed\n"); + 1ce3: 83 ec 08 sub $0x8,%esp + 1ce6: 68 7e 44 00 00 push $0x447e + 1ceb: 6a 01 push $0x1 + 1ced: e8 4e 1d 00 00 call 3a40 + exit(); + 1cf2: e8 dc 1b 00 00 call 38d3 + printf(1, "bigdir unlink failed"); + 1cf7: 83 ec 08 sub $0x8,%esp + 1cfa: 68 92 44 00 00 push $0x4492 + 1cff: 6a 01 push $0x1 + 1d01: e8 3a 1d 00 00 call 3a40 + exit(); + 1d06: e8 c8 1b 00 00 call 38d3 + printf(1, "bigdir create failed\n"); + 1d0b: 50 push %eax + 1d0c: 50 push %eax + 1d0d: 68 68 44 00 00 push $0x4468 + 1d12: 6a 01 push $0x1 + 1d14: e8 27 1d 00 00 call 3a40 + exit(); + 1d19: e8 b5 1b 00 00 call 38d3 + 1d1e: 66 90 xchg %ax,%ax + +00001d20 : +void subdir(void) { + 1d20: 55 push %ebp + 1d21: 89 e5 mov %esp,%ebp + 1d23: 53 push %ebx + 1d24: 83 ec 0c sub $0xc,%esp + printf(1, "subdir test\n"); + 1d27: 68 b2 44 00 00 push $0x44b2 + 1d2c: 6a 01 push $0x1 + 1d2e: e8 0d 1d 00 00 call 3a40 + unlink("ff"); + 1d33: c7 04 24 3b 45 00 00 movl $0x453b,(%esp) + 1d3a: e8 14 1c 00 00 call 3953 + if (mkdir("dd") != 0) { + 1d3f: c7 04 24 d8 45 00 00 movl $0x45d8,(%esp) + 1d46: e8 18 1c 00 00 call 3963 + 1d4b: 83 c4 10 add $0x10,%esp + 1d4e: 85 c0 test %eax,%eax + 1d50: 0f 85 b3 05 00 00 jne 2309 + fd = open("dd/ff", O_CREATE | O_RDWR); + 1d56: 83 ec 08 sub $0x8,%esp + 1d59: 68 02 02 00 00 push $0x202 + 1d5e: 68 11 45 00 00 push $0x4511 + 1d63: e8 d3 1b 00 00 call 393b + if (fd < 0) { + 1d68: 83 c4 10 add $0x10,%esp + fd = open("dd/ff", O_CREATE | O_RDWR); + 1d6b: 89 c3 mov %eax,%ebx + if (fd < 0) { + 1d6d: 85 c0 test %eax,%eax + 1d6f: 0f 88 81 05 00 00 js 22f6 + write(fd, "ff", 2); + 1d75: 83 ec 04 sub $0x4,%esp + 1d78: 6a 02 push $0x2 + 1d7a: 68 3b 45 00 00 push $0x453b + 1d7f: 50 push %eax + 1d80: e8 be 1b 00 00 call 3943 + close(fd); + 1d85: 89 1c 24 mov %ebx,(%esp) + 1d88: e8 de 1b 00 00 call 396b + if (unlink("dd") >= 0) { + 1d8d: c7 04 24 d8 45 00 00 movl $0x45d8,(%esp) + 1d94: e8 ba 1b 00 00 call 3953 + 1d99: 83 c4 10 add $0x10,%esp + 1d9c: 85 c0 test %eax,%eax + 1d9e: 0f 89 3f 05 00 00 jns 22e3 + if (mkdir("/dd/dd") != 0) { + 1da4: 83 ec 0c sub $0xc,%esp + 1da7: 68 ec 44 00 00 push $0x44ec + 1dac: e8 b2 1b 00 00 call 3963 + 1db1: 83 c4 10 add $0x10,%esp + 1db4: 85 c0 test %eax,%eax + 1db6: 0f 85 14 05 00 00 jne 22d0 + fd = open("dd/dd/ff", O_CREATE | O_RDWR); + 1dbc: 83 ec 08 sub $0x8,%esp + 1dbf: 68 02 02 00 00 push $0x202 + 1dc4: 68 0e 45 00 00 push $0x450e + 1dc9: e8 6d 1b 00 00 call 393b + if (fd < 0) { + 1dce: 83 c4 10 add $0x10,%esp + fd = open("dd/dd/ff", O_CREATE | O_RDWR); + 1dd1: 89 c3 mov %eax,%ebx + if (fd < 0) { + 1dd3: 85 c0 test %eax,%eax + 1dd5: 0f 88 24 04 00 00 js 21ff + write(fd, "FF", 2); + 1ddb: 83 ec 04 sub $0x4,%esp + 1dde: 6a 02 push $0x2 + 1de0: 68 2f 45 00 00 push $0x452f + 1de5: 50 push %eax + 1de6: e8 58 1b 00 00 call 3943 + close(fd); + 1deb: 89 1c 24 mov %ebx,(%esp) + 1dee: e8 78 1b 00 00 call 396b + fd = open("dd/dd/../ff", 0); + 1df3: 58 pop %eax + 1df4: 5a pop %edx + 1df5: 6a 00 push $0x0 + 1df7: 68 32 45 00 00 push $0x4532 + 1dfc: e8 3a 1b 00 00 call 393b + if (fd < 0) { + 1e01: 83 c4 10 add $0x10,%esp + fd = open("dd/dd/../ff", 0); + 1e04: 89 c3 mov %eax,%ebx + if (fd < 0) { + 1e06: 85 c0 test %eax,%eax + 1e08: 0f 88 de 03 00 00 js 21ec + cc = read(fd, buf, sizeof(buf)); + 1e0e: 83 ec 04 sub $0x4,%esp + 1e11: 68 00 20 00 00 push $0x2000 + 1e16: 68 a0 85 00 00 push $0x85a0 + 1e1b: 50 push %eax + 1e1c: e8 ca 1a 00 00 call 38eb + if (cc != 2 || buf[0] != 'f') { + 1e21: 83 c4 10 add $0x10,%esp + 1e24: 83 f8 02 cmp $0x2,%eax + 1e27: 0f 85 3a 03 00 00 jne 2167 + 1e2d: 80 3d a0 85 00 00 66 cmpb $0x66,0x85a0 + 1e34: 0f 85 2d 03 00 00 jne 2167 + close(fd); + 1e3a: 83 ec 0c sub $0xc,%esp + 1e3d: 53 push %ebx + 1e3e: e8 28 1b 00 00 call 396b + if (link("dd/dd/ff", "dd/dd/ffff") != 0) { + 1e43: 59 pop %ecx + 1e44: 5b pop %ebx + 1e45: 68 72 45 00 00 push $0x4572 + 1e4a: 68 0e 45 00 00 push $0x450e + 1e4f: e8 07 1b 00 00 call 395b + 1e54: 83 c4 10 add $0x10,%esp + 1e57: 85 c0 test %eax,%eax + 1e59: 0f 85 c6 03 00 00 jne 2225 + if (unlink("dd/dd/ff") != 0) { + 1e5f: 83 ec 0c sub $0xc,%esp + 1e62: 68 0e 45 00 00 push $0x450e + 1e67: e8 e7 1a 00 00 call 3953 + 1e6c: 83 c4 10 add $0x10,%esp + 1e6f: 85 c0 test %eax,%eax + 1e71: 0f 85 16 03 00 00 jne 218d + if (open("dd/dd/ff", O_RDONLY) >= 0) { + 1e77: 83 ec 08 sub $0x8,%esp + 1e7a: 6a 00 push $0x0 + 1e7c: 68 0e 45 00 00 push $0x450e + 1e81: e8 b5 1a 00 00 call 393b + 1e86: 83 c4 10 add $0x10,%esp + 1e89: 85 c0 test %eax,%eax + 1e8b: 0f 89 2c 04 00 00 jns 22bd + if (chdir("dd") != 0) { + 1e91: 83 ec 0c sub $0xc,%esp + 1e94: 68 d8 45 00 00 push $0x45d8 + 1e99: e8 6d 1a 00 00 call 390b + 1e9e: 83 c4 10 add $0x10,%esp + 1ea1: 85 c0 test %eax,%eax + 1ea3: 0f 85 01 04 00 00 jne 22aa + if (chdir("dd/../../dd") != 0) { + 1ea9: 83 ec 0c sub $0xc,%esp + 1eac: 68 a6 45 00 00 push $0x45a6 + 1eb1: e8 55 1a 00 00 call 390b + 1eb6: 83 c4 10 add $0x10,%esp + 1eb9: 85 c0 test %eax,%eax + 1ebb: 0f 85 b9 02 00 00 jne 217a + if (chdir("dd/../../../dd") != 0) { + 1ec1: 83 ec 0c sub $0xc,%esp + 1ec4: 68 cc 45 00 00 push $0x45cc + 1ec9: e8 3d 1a 00 00 call 390b + 1ece: 83 c4 10 add $0x10,%esp + 1ed1: 85 c0 test %eax,%eax + 1ed3: 0f 85 a1 02 00 00 jne 217a + if (chdir("./..") != 0) { + 1ed9: 83 ec 0c sub $0xc,%esp + 1edc: 68 db 45 00 00 push $0x45db + 1ee1: e8 25 1a 00 00 call 390b + 1ee6: 83 c4 10 add $0x10,%esp + 1ee9: 85 c0 test %eax,%eax + 1eeb: 0f 85 21 03 00 00 jne 2212 + fd = open("dd/dd/ffff", 0); + 1ef1: 83 ec 08 sub $0x8,%esp + 1ef4: 6a 00 push $0x0 + 1ef6: 68 72 45 00 00 push $0x4572 + 1efb: e8 3b 1a 00 00 call 393b + if (fd < 0) { + 1f00: 83 c4 10 add $0x10,%esp + fd = open("dd/dd/ffff", 0); + 1f03: 89 c3 mov %eax,%ebx + if (fd < 0) { + 1f05: 85 c0 test %eax,%eax + 1f07: 0f 88 e0 04 00 00 js 23ed + if (read(fd, buf, sizeof(buf)) != 2) { + 1f0d: 83 ec 04 sub $0x4,%esp + 1f10: 68 00 20 00 00 push $0x2000 + 1f15: 68 a0 85 00 00 push $0x85a0 + 1f1a: 50 push %eax + 1f1b: e8 cb 19 00 00 call 38eb + 1f20: 83 c4 10 add $0x10,%esp + 1f23: 83 f8 02 cmp $0x2,%eax + 1f26: 0f 85 ae 04 00 00 jne 23da + close(fd); + 1f2c: 83 ec 0c sub $0xc,%esp + 1f2f: 53 push %ebx + 1f30: e8 36 1a 00 00 call 396b + if (open("dd/dd/ff", O_RDONLY) >= 0) { + 1f35: 58 pop %eax + 1f36: 5a pop %edx + 1f37: 6a 00 push $0x0 + 1f39: 68 0e 45 00 00 push $0x450e + 1f3e: e8 f8 19 00 00 call 393b + 1f43: 83 c4 10 add $0x10,%esp + 1f46: 85 c0 test %eax,%eax + 1f48: 0f 89 65 02 00 00 jns 21b3 + if (open("dd/ff/ff", O_CREATE | O_RDWR) >= 0) { + 1f4e: 83 ec 08 sub $0x8,%esp + 1f51: 68 02 02 00 00 push $0x202 + 1f56: 68 26 46 00 00 push $0x4626 + 1f5b: e8 db 19 00 00 call 393b + 1f60: 83 c4 10 add $0x10,%esp + 1f63: 85 c0 test %eax,%eax + 1f65: 0f 89 35 02 00 00 jns 21a0 + if (open("dd/xx/ff", O_CREATE | O_RDWR) >= 0) { + 1f6b: 83 ec 08 sub $0x8,%esp + 1f6e: 68 02 02 00 00 push $0x202 + 1f73: 68 4b 46 00 00 push $0x464b + 1f78: e8 be 19 00 00 call 393b + 1f7d: 83 c4 10 add $0x10,%esp + 1f80: 85 c0 test %eax,%eax + 1f82: 0f 89 0f 03 00 00 jns 2297 + if (open("dd", O_CREATE) >= 0) { + 1f88: 83 ec 08 sub $0x8,%esp + 1f8b: 68 00 02 00 00 push $0x200 + 1f90: 68 d8 45 00 00 push $0x45d8 + 1f95: e8 a1 19 00 00 call 393b + 1f9a: 83 c4 10 add $0x10,%esp + 1f9d: 85 c0 test %eax,%eax + 1f9f: 0f 89 df 02 00 00 jns 2284 + if (open("dd", O_RDWR) >= 0) { + 1fa5: 83 ec 08 sub $0x8,%esp + 1fa8: 6a 02 push $0x2 + 1faa: 68 d8 45 00 00 push $0x45d8 + 1faf: e8 87 19 00 00 call 393b + 1fb4: 83 c4 10 add $0x10,%esp + 1fb7: 85 c0 test %eax,%eax + 1fb9: 0f 89 b2 02 00 00 jns 2271 + if (open("dd", O_WRONLY) >= 0) { + 1fbf: 83 ec 08 sub $0x8,%esp + 1fc2: 6a 01 push $0x1 + 1fc4: 68 d8 45 00 00 push $0x45d8 + 1fc9: e8 6d 19 00 00 call 393b + 1fce: 83 c4 10 add $0x10,%esp + 1fd1: 85 c0 test %eax,%eax + 1fd3: 0f 89 85 02 00 00 jns 225e + if (link("dd/ff/ff", "dd/dd/xx") == 0) { + 1fd9: 83 ec 08 sub $0x8,%esp + 1fdc: 68 ba 46 00 00 push $0x46ba + 1fe1: 68 26 46 00 00 push $0x4626 + 1fe6: e8 70 19 00 00 call 395b + 1feb: 83 c4 10 add $0x10,%esp + 1fee: 85 c0 test %eax,%eax + 1ff0: 0f 84 55 02 00 00 je 224b + if (link("dd/xx/ff", "dd/dd/xx") == 0) { + 1ff6: 83 ec 08 sub $0x8,%esp + 1ff9: 68 ba 46 00 00 push $0x46ba + 1ffe: 68 4b 46 00 00 push $0x464b + 2003: e8 53 19 00 00 call 395b + 2008: 83 c4 10 add $0x10,%esp + 200b: 85 c0 test %eax,%eax + 200d: 0f 84 25 02 00 00 je 2238 + if (link("dd/ff", "dd/dd/ffff") == 0) { + 2013: 83 ec 08 sub $0x8,%esp + 2016: 68 72 45 00 00 push $0x4572 + 201b: 68 11 45 00 00 push $0x4511 + 2020: e8 36 19 00 00 call 395b + 2025: 83 c4 10 add $0x10,%esp + 2028: 85 c0 test %eax,%eax + 202a: 0f 84 a9 01 00 00 je 21d9 + if (mkdir("dd/ff/ff") == 0) { + 2030: 83 ec 0c sub $0xc,%esp + 2033: 68 26 46 00 00 push $0x4626 + 2038: e8 26 19 00 00 call 3963 + 203d: 83 c4 10 add $0x10,%esp + 2040: 85 c0 test %eax,%eax + 2042: 0f 84 7e 01 00 00 je 21c6 + if (mkdir("dd/xx/ff") == 0) { + 2048: 83 ec 0c sub $0xc,%esp + 204b: 68 4b 46 00 00 push $0x464b + 2050: e8 0e 19 00 00 call 3963 + 2055: 83 c4 10 add $0x10,%esp + 2058: 85 c0 test %eax,%eax + 205a: 0f 84 67 03 00 00 je 23c7 + if (mkdir("dd/dd/ffff") == 0) { + 2060: 83 ec 0c sub $0xc,%esp + 2063: 68 72 45 00 00 push $0x4572 + 2068: e8 f6 18 00 00 call 3963 + 206d: 83 c4 10 add $0x10,%esp + 2070: 85 c0 test %eax,%eax + 2072: 0f 84 3c 03 00 00 je 23b4 + if (unlink("dd/xx/ff") == 0) { + 2078: 83 ec 0c sub $0xc,%esp + 207b: 68 4b 46 00 00 push $0x464b + 2080: e8 ce 18 00 00 call 3953 + 2085: 83 c4 10 add $0x10,%esp + 2088: 85 c0 test %eax,%eax + 208a: 0f 84 11 03 00 00 je 23a1 + if (unlink("dd/ff/ff") == 0) { + 2090: 83 ec 0c sub $0xc,%esp + 2093: 68 26 46 00 00 push $0x4626 + 2098: e8 b6 18 00 00 call 3953 + 209d: 83 c4 10 add $0x10,%esp + 20a0: 85 c0 test %eax,%eax + 20a2: 0f 84 e6 02 00 00 je 238e + if (chdir("dd/ff") == 0) { + 20a8: 83 ec 0c sub $0xc,%esp + 20ab: 68 11 45 00 00 push $0x4511 + 20b0: e8 56 18 00 00 call 390b + 20b5: 83 c4 10 add $0x10,%esp + 20b8: 85 c0 test %eax,%eax + 20ba: 0f 84 bb 02 00 00 je 237b + if (chdir("dd/xx") == 0) { + 20c0: 83 ec 0c sub $0xc,%esp + 20c3: 68 bd 46 00 00 push $0x46bd + 20c8: e8 3e 18 00 00 call 390b + 20cd: 83 c4 10 add $0x10,%esp + 20d0: 85 c0 test %eax,%eax + 20d2: 0f 84 90 02 00 00 je 2368 + if (unlink("dd/dd/ffff") != 0) { + 20d8: 83 ec 0c sub $0xc,%esp + 20db: 68 72 45 00 00 push $0x4572 + 20e0: e8 6e 18 00 00 call 3953 + 20e5: 83 c4 10 add $0x10,%esp + 20e8: 85 c0 test %eax,%eax + 20ea: 0f 85 9d 00 00 00 jne 218d + if (unlink("dd/ff") != 0) { + 20f0: 83 ec 0c sub $0xc,%esp + 20f3: 68 11 45 00 00 push $0x4511 + 20f8: e8 56 18 00 00 call 3953 + 20fd: 83 c4 10 add $0x10,%esp + 2100: 85 c0 test %eax,%eax + 2102: 0f 85 4d 02 00 00 jne 2355 + if (unlink("dd") == 0) { + 2108: 83 ec 0c sub $0xc,%esp + 210b: 68 d8 45 00 00 push $0x45d8 + 2110: e8 3e 18 00 00 call 3953 + 2115: 83 c4 10 add $0x10,%esp + 2118: 85 c0 test %eax,%eax + 211a: 0f 84 22 02 00 00 je 2342 + if (unlink("dd/dd") < 0) { + 2120: 83 ec 0c sub $0xc,%esp + 2123: 68 ed 44 00 00 push $0x44ed + 2128: e8 26 18 00 00 call 3953 + 212d: 83 c4 10 add $0x10,%esp + 2130: 85 c0 test %eax,%eax + 2132: 0f 88 f7 01 00 00 js 232f + if (unlink("dd") < 0) { + 2138: 83 ec 0c sub $0xc,%esp + 213b: 68 d8 45 00 00 push $0x45d8 + 2140: e8 0e 18 00 00 call 3953 + 2145: 83 c4 10 add $0x10,%esp + 2148: 85 c0 test %eax,%eax + 214a: 0f 88 cc 01 00 00 js 231c + printf(1, "subdir ok\n"); + 2150: 83 ec 08 sub $0x8,%esp + 2153: 68 ba 47 00 00 push $0x47ba + 2158: 6a 01 push $0x1 + 215a: e8 e1 18 00 00 call 3a40 +} + 215f: 8b 5d fc mov -0x4(%ebp),%ebx + 2162: 83 c4 10 add $0x10,%esp + 2165: c9 leave + 2166: c3 ret + printf(1, "dd/dd/../ff wrong content\n"); + 2167: 50 push %eax + 2168: 50 push %eax + 2169: 68 57 45 00 00 push $0x4557 + 216e: 6a 01 push $0x1 + 2170: e8 cb 18 00 00 call 3a40 + exit(); + 2175: e8 59 17 00 00 call 38d3 + printf(1, "chdir dd/../../dd failed\n"); + 217a: 50 push %eax + 217b: 50 push %eax + 217c: 68 b2 45 00 00 push $0x45b2 + 2181: 6a 01 push $0x1 + 2183: e8 b8 18 00 00 call 3a40 + exit(); + 2188: e8 46 17 00 00 call 38d3 + printf(1, "unlink dd/dd/ff failed\n"); + 218d: 50 push %eax + 218e: 50 push %eax + 218f: 68 7d 45 00 00 push $0x457d + 2194: 6a 01 push $0x1 + 2196: e8 a5 18 00 00 call 3a40 + exit(); + 219b: e8 33 17 00 00 call 38d3 + printf(1, "create dd/ff/ff succeeded!\n"); + 21a0: 51 push %ecx + 21a1: 51 push %ecx + 21a2: 68 2f 46 00 00 push $0x462f + 21a7: 6a 01 push $0x1 + 21a9: e8 92 18 00 00 call 3a40 + exit(); + 21ae: e8 20 17 00 00 call 38d3 + printf(1, "open (unlinked) dd/dd/ff succeeded!\n"); + 21b3: 53 push %ebx + 21b4: 53 push %ebx + 21b5: 68 14 50 00 00 push $0x5014 + 21ba: 6a 01 push $0x1 + 21bc: e8 7f 18 00 00 call 3a40 + exit(); + 21c1: e8 0d 17 00 00 call 38d3 + printf(1, "mkdir dd/ff/ff succeeded!\n"); + 21c6: 51 push %ecx + 21c7: 51 push %ecx + 21c8: 68 c3 46 00 00 push $0x46c3 + 21cd: 6a 01 push $0x1 + 21cf: e8 6c 18 00 00 call 3a40 + exit(); + 21d4: e8 fa 16 00 00 call 38d3 + printf(1, "link dd/ff dd/dd/ffff succeeded!\n"); + 21d9: 53 push %ebx + 21da: 53 push %ebx + 21db: 68 84 50 00 00 push $0x5084 + 21e0: 6a 01 push $0x1 + 21e2: e8 59 18 00 00 call 3a40 + exit(); + 21e7: e8 e7 16 00 00 call 38d3 + printf(1, "open dd/dd/../ff failed\n"); + 21ec: 50 push %eax + 21ed: 50 push %eax + 21ee: 68 3e 45 00 00 push $0x453e + 21f3: 6a 01 push $0x1 + 21f5: e8 46 18 00 00 call 3a40 + exit(); + 21fa: e8 d4 16 00 00 call 38d3 + printf(1, "create dd/dd/ff failed\n"); + 21ff: 51 push %ecx + 2200: 51 push %ecx + 2201: 68 17 45 00 00 push $0x4517 + 2206: 6a 01 push $0x1 + 2208: e8 33 18 00 00 call 3a40 + exit(); + 220d: e8 c1 16 00 00 call 38d3 + printf(1, "chdir ./.. failed\n"); + 2212: 50 push %eax + 2213: 50 push %eax + 2214: 68 e0 45 00 00 push $0x45e0 + 2219: 6a 01 push $0x1 + 221b: e8 20 18 00 00 call 3a40 + exit(); + 2220: e8 ae 16 00 00 call 38d3 + printf(1, "link dd/dd/ff dd/dd/ffff failed\n"); + 2225: 52 push %edx + 2226: 52 push %edx + 2227: 68 cc 4f 00 00 push $0x4fcc + 222c: 6a 01 push $0x1 + 222e: e8 0d 18 00 00 call 3a40 + exit(); + 2233: e8 9b 16 00 00 call 38d3 + printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n"); + 2238: 50 push %eax + 2239: 50 push %eax + 223a: 68 60 50 00 00 push $0x5060 + 223f: 6a 01 push $0x1 + 2241: e8 fa 17 00 00 call 3a40 + exit(); + 2246: e8 88 16 00 00 call 38d3 + printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n"); + 224b: 50 push %eax + 224c: 50 push %eax + 224d: 68 3c 50 00 00 push $0x503c + 2252: 6a 01 push $0x1 + 2254: e8 e7 17 00 00 call 3a40 + exit(); + 2259: e8 75 16 00 00 call 38d3 + printf(1, "open dd wronly succeeded!\n"); + 225e: 50 push %eax + 225f: 50 push %eax + 2260: 68 9f 46 00 00 push $0x469f + 2265: 6a 01 push $0x1 + 2267: e8 d4 17 00 00 call 3a40 + exit(); + 226c: e8 62 16 00 00 call 38d3 + printf(1, "open dd rdwr succeeded!\n"); + 2271: 50 push %eax + 2272: 50 push %eax + 2273: 68 86 46 00 00 push $0x4686 + 2278: 6a 01 push $0x1 + 227a: e8 c1 17 00 00 call 3a40 + exit(); + 227f: e8 4f 16 00 00 call 38d3 + printf(1, "create dd succeeded!\n"); + 2284: 50 push %eax + 2285: 50 push %eax + 2286: 68 70 46 00 00 push $0x4670 + 228b: 6a 01 push $0x1 + 228d: e8 ae 17 00 00 call 3a40 + exit(); + 2292: e8 3c 16 00 00 call 38d3 + printf(1, "create dd/xx/ff succeeded!\n"); + 2297: 52 push %edx + 2298: 52 push %edx + 2299: 68 54 46 00 00 push $0x4654 + 229e: 6a 01 push $0x1 + 22a0: e8 9b 17 00 00 call 3a40 + exit(); + 22a5: e8 29 16 00 00 call 38d3 + printf(1, "chdir dd failed\n"); + 22aa: 50 push %eax + 22ab: 50 push %eax + 22ac: 68 95 45 00 00 push $0x4595 + 22b1: 6a 01 push $0x1 + 22b3: e8 88 17 00 00 call 3a40 + exit(); + 22b8: e8 16 16 00 00 call 38d3 + printf(1, "open (unlinked) dd/dd/ff succeeded\n"); + 22bd: 50 push %eax + 22be: 50 push %eax + 22bf: 68 f0 4f 00 00 push $0x4ff0 + 22c4: 6a 01 push $0x1 + 22c6: e8 75 17 00 00 call 3a40 + exit(); + 22cb: e8 03 16 00 00 call 38d3 + printf(1, "subdir mkdir dd/dd failed\n"); + 22d0: 53 push %ebx + 22d1: 53 push %ebx + 22d2: 68 f3 44 00 00 push $0x44f3 + 22d7: 6a 01 push $0x1 + 22d9: e8 62 17 00 00 call 3a40 + exit(); + 22de: e8 f0 15 00 00 call 38d3 + printf(1, "unlink dd (non-empty dir) succeeded!\n"); + 22e3: 50 push %eax + 22e4: 50 push %eax + 22e5: 68 a4 4f 00 00 push $0x4fa4 + 22ea: 6a 01 push $0x1 + 22ec: e8 4f 17 00 00 call 3a40 + exit(); + 22f1: e8 dd 15 00 00 call 38d3 + printf(1, "create dd/ff failed\n"); + 22f6: 50 push %eax + 22f7: 50 push %eax + 22f8: 68 d7 44 00 00 push $0x44d7 + 22fd: 6a 01 push $0x1 + 22ff: e8 3c 17 00 00 call 3a40 + exit(); + 2304: e8 ca 15 00 00 call 38d3 + printf(1, "subdir mkdir dd failed\n"); + 2309: 50 push %eax + 230a: 50 push %eax + 230b: 68 bf 44 00 00 push $0x44bf + 2310: 6a 01 push $0x1 + 2312: e8 29 17 00 00 call 3a40 + exit(); + 2317: e8 b7 15 00 00 call 38d3 + printf(1, "unlink dd failed\n"); + 231c: 50 push %eax + 231d: 50 push %eax + 231e: 68 a8 47 00 00 push $0x47a8 + 2323: 6a 01 push $0x1 + 2325: e8 16 17 00 00 call 3a40 + exit(); + 232a: e8 a4 15 00 00 call 38d3 + printf(1, "unlink dd/dd failed\n"); + 232f: 52 push %edx + 2330: 52 push %edx + 2331: 68 93 47 00 00 push $0x4793 + 2336: 6a 01 push $0x1 + 2338: e8 03 17 00 00 call 3a40 + exit(); + 233d: e8 91 15 00 00 call 38d3 + printf(1, "unlink non-empty dd succeeded!\n"); + 2342: 51 push %ecx + 2343: 51 push %ecx + 2344: 68 a8 50 00 00 push $0x50a8 + 2349: 6a 01 push $0x1 + 234b: e8 f0 16 00 00 call 3a40 + exit(); + 2350: e8 7e 15 00 00 call 38d3 + printf(1, "unlink dd/ff failed\n"); + 2355: 53 push %ebx + 2356: 53 push %ebx + 2357: 68 7e 47 00 00 push $0x477e + 235c: 6a 01 push $0x1 + 235e: e8 dd 16 00 00 call 3a40 + exit(); + 2363: e8 6b 15 00 00 call 38d3 + printf(1, "chdir dd/xx succeeded!\n"); + 2368: 50 push %eax + 2369: 50 push %eax + 236a: 68 66 47 00 00 push $0x4766 + 236f: 6a 01 push $0x1 + 2371: e8 ca 16 00 00 call 3a40 + exit(); + 2376: e8 58 15 00 00 call 38d3 + printf(1, "chdir dd/ff succeeded!\n"); + 237b: 50 push %eax + 237c: 50 push %eax + 237d: 68 4e 47 00 00 push $0x474e + 2382: 6a 01 push $0x1 + 2384: e8 b7 16 00 00 call 3a40 + exit(); + 2389: e8 45 15 00 00 call 38d3 + printf(1, "unlink dd/ff/ff succeeded!\n"); + 238e: 50 push %eax + 238f: 50 push %eax + 2390: 68 32 47 00 00 push $0x4732 + 2395: 6a 01 push $0x1 + 2397: e8 a4 16 00 00 call 3a40 + exit(); + 239c: e8 32 15 00 00 call 38d3 + printf(1, "unlink dd/xx/ff succeeded!\n"); + 23a1: 50 push %eax + 23a2: 50 push %eax + 23a3: 68 16 47 00 00 push $0x4716 + 23a8: 6a 01 push $0x1 + 23aa: e8 91 16 00 00 call 3a40 + exit(); + 23af: e8 1f 15 00 00 call 38d3 + printf(1, "mkdir dd/dd/ffff succeeded!\n"); + 23b4: 50 push %eax + 23b5: 50 push %eax + 23b6: 68 f9 46 00 00 push $0x46f9 + 23bb: 6a 01 push $0x1 + 23bd: e8 7e 16 00 00 call 3a40 + exit(); + 23c2: e8 0c 15 00 00 call 38d3 + printf(1, "mkdir dd/xx/ff succeeded!\n"); + 23c7: 52 push %edx + 23c8: 52 push %edx + 23c9: 68 de 46 00 00 push $0x46de + 23ce: 6a 01 push $0x1 + 23d0: e8 6b 16 00 00 call 3a40 + exit(); + 23d5: e8 f9 14 00 00 call 38d3 + printf(1, "read dd/dd/ffff wrong len\n"); + 23da: 51 push %ecx + 23db: 51 push %ecx + 23dc: 68 0b 46 00 00 push $0x460b + 23e1: 6a 01 push $0x1 + 23e3: e8 58 16 00 00 call 3a40 + exit(); + 23e8: e8 e6 14 00 00 call 38d3 + printf(1, "open dd/dd/ffff failed\n"); + 23ed: 53 push %ebx + 23ee: 53 push %ebx + 23ef: 68 f3 45 00 00 push $0x45f3 + 23f4: 6a 01 push $0x1 + 23f6: e8 45 16 00 00 call 3a40 + exit(); + 23fb: e8 d3 14 00 00 call 38d3 + +00002400 : +void bigwrite(void) { + 2400: 55 push %ebp + 2401: 89 e5 mov %esp,%ebp + 2403: 56 push %esi + 2404: 53 push %ebx + for (sz = 499; sz < 12 * 512; sz += 471) { + 2405: bb f3 01 00 00 mov $0x1f3,%ebx + printf(1, "bigwrite test\n"); + 240a: 83 ec 08 sub $0x8,%esp + 240d: 68 c5 47 00 00 push $0x47c5 + 2412: 6a 01 push $0x1 + 2414: e8 27 16 00 00 call 3a40 + unlink("bigwrite"); + 2419: c7 04 24 d4 47 00 00 movl $0x47d4,(%esp) + 2420: e8 2e 15 00 00 call 3953 + 2425: 83 c4 10 add $0x10,%esp + 2428: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 242f: 90 nop + fd = open("bigwrite", O_CREATE | O_RDWR); + 2430: 83 ec 08 sub $0x8,%esp + 2433: 68 02 02 00 00 push $0x202 + 2438: 68 d4 47 00 00 push $0x47d4 + 243d: e8 f9 14 00 00 call 393b + if (fd < 0) { + 2442: 83 c4 10 add $0x10,%esp + fd = open("bigwrite", O_CREATE | O_RDWR); + 2445: 89 c6 mov %eax,%esi + if (fd < 0) { + 2447: 85 c0 test %eax,%eax + 2449: 78 7e js 24c9 + int cc = write(fd, buf, sz); + 244b: 83 ec 04 sub $0x4,%esp + 244e: 53 push %ebx + 244f: 68 a0 85 00 00 push $0x85a0 + 2454: 50 push %eax + 2455: e8 e9 14 00 00 call 3943 + if (cc != sz) { + 245a: 83 c4 10 add $0x10,%esp + 245d: 39 d8 cmp %ebx,%eax + 245f: 75 55 jne 24b6 + int cc = write(fd, buf, sz); + 2461: 83 ec 04 sub $0x4,%esp + 2464: 53 push %ebx + 2465: 68 a0 85 00 00 push $0x85a0 + 246a: 56 push %esi + 246b: e8 d3 14 00 00 call 3943 + if (cc != sz) { + 2470: 83 c4 10 add $0x10,%esp + 2473: 39 d8 cmp %ebx,%eax + 2475: 75 3f jne 24b6 + close(fd); + 2477: 83 ec 0c sub $0xc,%esp + for (sz = 499; sz < 12 * 512; sz += 471) { + 247a: 81 c3 d7 01 00 00 add $0x1d7,%ebx + close(fd); + 2480: 56 push %esi + 2481: e8 e5 14 00 00 call 396b + unlink("bigwrite"); + 2486: c7 04 24 d4 47 00 00 movl $0x47d4,(%esp) + 248d: e8 c1 14 00 00 call 3953 + for (sz = 499; sz < 12 * 512; sz += 471) { + 2492: 83 c4 10 add $0x10,%esp + 2495: 81 fb 07 18 00 00 cmp $0x1807,%ebx + 249b: 75 93 jne 2430 + printf(1, "bigwrite ok\n"); + 249d: 83 ec 08 sub $0x8,%esp + 24a0: 68 07 48 00 00 push $0x4807 + 24a5: 6a 01 push $0x1 + 24a7: e8 94 15 00 00 call 3a40 +} + 24ac: 83 c4 10 add $0x10,%esp + 24af: 8d 65 f8 lea -0x8(%ebp),%esp + 24b2: 5b pop %ebx + 24b3: 5e pop %esi + 24b4: 5d pop %ebp + 24b5: c3 ret + printf(1, "write(%d) ret %d\n", sz, cc); + 24b6: 50 push %eax + 24b7: 53 push %ebx + 24b8: 68 f5 47 00 00 push $0x47f5 + 24bd: 6a 01 push $0x1 + 24bf: e8 7c 15 00 00 call 3a40 + exit(); + 24c4: e8 0a 14 00 00 call 38d3 + printf(1, "cannot create bigwrite\n"); + 24c9: 83 ec 08 sub $0x8,%esp + 24cc: 68 dd 47 00 00 push $0x47dd + 24d1: 6a 01 push $0x1 + 24d3: e8 68 15 00 00 call 3a40 + exit(); + 24d8: e8 f6 13 00 00 call 38d3 + 24dd: 8d 76 00 lea 0x0(%esi),%esi + +000024e0 : +void bigfile(void) { + 24e0: 55 push %ebp + 24e1: 89 e5 mov %esp,%ebp + 24e3: 57 push %edi + 24e4: 56 push %esi + 24e5: 53 push %ebx + 24e6: 83 ec 14 sub $0x14,%esp + printf(1, "bigfile test\n"); + 24e9: 68 14 48 00 00 push $0x4814 + 24ee: 6a 01 push $0x1 + 24f0: e8 4b 15 00 00 call 3a40 + unlink("bigfile"); + 24f5: c7 04 24 30 48 00 00 movl $0x4830,(%esp) + 24fc: e8 52 14 00 00 call 3953 + fd = open("bigfile", O_CREATE | O_RDWR); + 2501: 58 pop %eax + 2502: 5a pop %edx + 2503: 68 02 02 00 00 push $0x202 + 2508: 68 30 48 00 00 push $0x4830 + 250d: e8 29 14 00 00 call 393b + if (fd < 0) { + 2512: 83 c4 10 add $0x10,%esp + 2515: 85 c0 test %eax,%eax + 2517: 0f 88 5e 01 00 00 js 267b + 251d: 89 c6 mov %eax,%esi + for (i = 0; i < 20; i++) { + 251f: 31 db xor %ebx,%ebx + 2521: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + memset(buf, i, 600); + 2528: 83 ec 04 sub $0x4,%esp + 252b: 68 58 02 00 00 push $0x258 + 2530: 53 push %ebx + 2531: 68 a0 85 00 00 push $0x85a0 + 2536: e8 05 12 00 00 call 3740 + if (write(fd, buf, 600) != 600) { + 253b: 83 c4 0c add $0xc,%esp + 253e: 68 58 02 00 00 push $0x258 + 2543: 68 a0 85 00 00 push $0x85a0 + 2548: 56 push %esi + 2549: e8 f5 13 00 00 call 3943 + 254e: 83 c4 10 add $0x10,%esp + 2551: 3d 58 02 00 00 cmp $0x258,%eax + 2556: 0f 85 f8 00 00 00 jne 2654 + for (i = 0; i < 20; i++) { + 255c: 83 c3 01 add $0x1,%ebx + 255f: 83 fb 14 cmp $0x14,%ebx + 2562: 75 c4 jne 2528 + close(fd); + 2564: 83 ec 0c sub $0xc,%esp + 2567: 56 push %esi + 2568: e8 fe 13 00 00 call 396b + fd = open("bigfile", 0); + 256d: 5e pop %esi + 256e: 5f pop %edi + 256f: 6a 00 push $0x0 + 2571: 68 30 48 00 00 push $0x4830 + 2576: e8 c0 13 00 00 call 393b + if (fd < 0) { + 257b: 83 c4 10 add $0x10,%esp + fd = open("bigfile", 0); + 257e: 89 c6 mov %eax,%esi + if (fd < 0) { + 2580: 85 c0 test %eax,%eax + 2582: 0f 88 e0 00 00 00 js 2668 + total = 0; + 2588: 31 db xor %ebx,%ebx + for (i = 0;; i++) { + 258a: 31 ff xor %edi,%edi + 258c: eb 30 jmp 25be + 258e: 66 90 xchg %ax,%ax + if (cc != 300) { + 2590: 3d 2c 01 00 00 cmp $0x12c,%eax + 2595: 0f 85 91 00 00 00 jne 262c + if (buf[0] != i / 2 || buf[299] != i / 2) { + 259b: 89 fa mov %edi,%edx + 259d: 0f be 05 a0 85 00 00 movsbl 0x85a0,%eax + 25a4: d1 fa sar %edx + 25a6: 39 d0 cmp %edx,%eax + 25a8: 75 6e jne 2618 + 25aa: 0f be 15 cb 86 00 00 movsbl 0x86cb,%edx + 25b1: 39 d0 cmp %edx,%eax + 25b3: 75 63 jne 2618 + total += cc; + 25b5: 81 c3 2c 01 00 00 add $0x12c,%ebx + for (i = 0;; i++) { + 25bb: 83 c7 01 add $0x1,%edi + cc = read(fd, buf, 300); + 25be: 83 ec 04 sub $0x4,%esp + 25c1: 68 2c 01 00 00 push $0x12c + 25c6: 68 a0 85 00 00 push $0x85a0 + 25cb: 56 push %esi + 25cc: e8 1a 13 00 00 call 38eb + if (cc < 0) { + 25d1: 83 c4 10 add $0x10,%esp + 25d4: 85 c0 test %eax,%eax + 25d6: 78 68 js 2640 + if (cc == 0) { + 25d8: 75 b6 jne 2590 + close(fd); + 25da: 83 ec 0c sub $0xc,%esp + 25dd: 56 push %esi + 25de: e8 88 13 00 00 call 396b + if (total != 20 * 600) { + 25e3: 83 c4 10 add $0x10,%esp + 25e6: 81 fb e0 2e 00 00 cmp $0x2ee0,%ebx + 25ec: 0f 85 9c 00 00 00 jne 268e + unlink("bigfile"); + 25f2: 83 ec 0c sub $0xc,%esp + 25f5: 68 30 48 00 00 push $0x4830 + 25fa: e8 54 13 00 00 call 3953 + printf(1, "bigfile test ok\n"); + 25ff: 58 pop %eax + 2600: 5a pop %edx + 2601: 68 bf 48 00 00 push $0x48bf + 2606: 6a 01 push $0x1 + 2608: e8 33 14 00 00 call 3a40 +} + 260d: 83 c4 10 add $0x10,%esp + 2610: 8d 65 f4 lea -0xc(%ebp),%esp + 2613: 5b pop %ebx + 2614: 5e pop %esi + 2615: 5f pop %edi + 2616: 5d pop %ebp + 2617: c3 ret + printf(1, "read bigfile wrong data\n"); + 2618: 83 ec 08 sub $0x8,%esp + 261b: 68 8c 48 00 00 push $0x488c + 2620: 6a 01 push $0x1 + 2622: e8 19 14 00 00 call 3a40 + exit(); + 2627: e8 a7 12 00 00 call 38d3 + printf(1, "short read bigfile\n"); + 262c: 83 ec 08 sub $0x8,%esp + 262f: 68 78 48 00 00 push $0x4878 + 2634: 6a 01 push $0x1 + 2636: e8 05 14 00 00 call 3a40 + exit(); + 263b: e8 93 12 00 00 call 38d3 + printf(1, "read bigfile failed\n"); + 2640: 83 ec 08 sub $0x8,%esp + 2643: 68 63 48 00 00 push $0x4863 + 2648: 6a 01 push $0x1 + 264a: e8 f1 13 00 00 call 3a40 + exit(); + 264f: e8 7f 12 00 00 call 38d3 + printf(1, "write bigfile failed\n"); + 2654: 83 ec 08 sub $0x8,%esp + 2657: 68 38 48 00 00 push $0x4838 + 265c: 6a 01 push $0x1 + 265e: e8 dd 13 00 00 call 3a40 + exit(); + 2663: e8 6b 12 00 00 call 38d3 + printf(1, "cannot open bigfile\n"); + 2668: 53 push %ebx + 2669: 53 push %ebx + 266a: 68 4e 48 00 00 push $0x484e + 266f: 6a 01 push $0x1 + 2671: e8 ca 13 00 00 call 3a40 + exit(); + 2676: e8 58 12 00 00 call 38d3 + printf(1, "cannot create bigfile"); + 267b: 50 push %eax + 267c: 50 push %eax + 267d: 68 22 48 00 00 push $0x4822 + 2682: 6a 01 push $0x1 + 2684: e8 b7 13 00 00 call 3a40 + exit(); + 2689: e8 45 12 00 00 call 38d3 + printf(1, "read bigfile wrong total\n"); + 268e: 51 push %ecx + 268f: 51 push %ecx + 2690: 68 a5 48 00 00 push $0x48a5 + 2695: 6a 01 push $0x1 + 2697: e8 a4 13 00 00 call 3a40 + exit(); + 269c: e8 32 12 00 00 call 38d3 + 26a1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 26a8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 26af: 90 nop + +000026b0 : +void fourteen(void) { + 26b0: 55 push %ebp + 26b1: 89 e5 mov %esp,%ebp + 26b3: 83 ec 10 sub $0x10,%esp + printf(1, "fourteen test\n"); + 26b6: 68 d0 48 00 00 push $0x48d0 + 26bb: 6a 01 push $0x1 + 26bd: e8 7e 13 00 00 call 3a40 + if (mkdir("12345678901234") != 0) { + 26c2: c7 04 24 0b 49 00 00 movl $0x490b,(%esp) + 26c9: e8 95 12 00 00 call 3963 + 26ce: 83 c4 10 add $0x10,%esp + 26d1: 85 c0 test %eax,%eax + 26d3: 0f 85 97 00 00 00 jne 2770 + if (mkdir("12345678901234/123456789012345") != 0) { + 26d9: 83 ec 0c sub $0xc,%esp + 26dc: 68 c8 50 00 00 push $0x50c8 + 26e1: e8 7d 12 00 00 call 3963 + 26e6: 83 c4 10 add $0x10,%esp + 26e9: 85 c0 test %eax,%eax + 26eb: 0f 85 de 00 00 00 jne 27cf + fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); + 26f1: 83 ec 08 sub $0x8,%esp + 26f4: 68 00 02 00 00 push $0x200 + 26f9: 68 18 51 00 00 push $0x5118 + 26fe: e8 38 12 00 00 call 393b + if (fd < 0) { + 2703: 83 c4 10 add $0x10,%esp + 2706: 85 c0 test %eax,%eax + 2708: 0f 88 ae 00 00 00 js 27bc + close(fd); + 270e: 83 ec 0c sub $0xc,%esp + 2711: 50 push %eax + 2712: e8 54 12 00 00 call 396b + fd = open("12345678901234/12345678901234/12345678901234", 0); + 2717: 58 pop %eax + 2718: 5a pop %edx + 2719: 6a 00 push $0x0 + 271b: 68 88 51 00 00 push $0x5188 + 2720: e8 16 12 00 00 call 393b + if (fd < 0) { + 2725: 83 c4 10 add $0x10,%esp + 2728: 85 c0 test %eax,%eax + 272a: 78 7d js 27a9 + close(fd); + 272c: 83 ec 0c sub $0xc,%esp + 272f: 50 push %eax + 2730: e8 36 12 00 00 call 396b + if (mkdir("12345678901234/12345678901234") == 0) { + 2735: c7 04 24 fc 48 00 00 movl $0x48fc,(%esp) + 273c: e8 22 12 00 00 call 3963 + 2741: 83 c4 10 add $0x10,%esp + 2744: 85 c0 test %eax,%eax + 2746: 74 4e je 2796 + if (mkdir("123456789012345/12345678901234") == 0) { + 2748: 83 ec 0c sub $0xc,%esp + 274b: 68 24 52 00 00 push $0x5224 + 2750: e8 0e 12 00 00 call 3963 + 2755: 83 c4 10 add $0x10,%esp + 2758: 85 c0 test %eax,%eax + 275a: 74 27 je 2783 + printf(1, "fourteen ok\n"); + 275c: 83 ec 08 sub $0x8,%esp + 275f: 68 1a 49 00 00 push $0x491a + 2764: 6a 01 push $0x1 + 2766: e8 d5 12 00 00 call 3a40 +} + 276b: 83 c4 10 add $0x10,%esp + 276e: c9 leave + 276f: c3 ret + printf(1, "mkdir 12345678901234 failed\n"); + 2770: 50 push %eax + 2771: 50 push %eax + 2772: 68 df 48 00 00 push $0x48df + 2777: 6a 01 push $0x1 + 2779: e8 c2 12 00 00 call 3a40 + exit(); + 277e: e8 50 11 00 00 call 38d3 + printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); + 2783: 50 push %eax + 2784: 50 push %eax + 2785: 68 44 52 00 00 push $0x5244 + 278a: 6a 01 push $0x1 + 278c: e8 af 12 00 00 call 3a40 + exit(); + 2791: e8 3d 11 00 00 call 38d3 + printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); + 2796: 52 push %edx + 2797: 52 push %edx + 2798: 68 f4 51 00 00 push $0x51f4 + 279d: 6a 01 push $0x1 + 279f: e8 9c 12 00 00 call 3a40 + exit(); + 27a4: e8 2a 11 00 00 call 38d3 + printf(1, "open 12345678901234/12345678901234/12345678901234 failed\n"); + 27a9: 51 push %ecx + 27aa: 51 push %ecx + 27ab: 68 b8 51 00 00 push $0x51b8 + 27b0: 6a 01 push $0x1 + 27b2: e8 89 12 00 00 call 3a40 + exit(); + 27b7: e8 17 11 00 00 call 38d3 + printf(1, "create 123456789012345/123456789012345/123456789012345 failed\n"); + 27bc: 51 push %ecx + 27bd: 51 push %ecx + 27be: 68 48 51 00 00 push $0x5148 + 27c3: 6a 01 push $0x1 + 27c5: e8 76 12 00 00 call 3a40 + exit(); + 27ca: e8 04 11 00 00 call 38d3 + printf(1, "mkdir 12345678901234/123456789012345 failed\n"); + 27cf: 50 push %eax + 27d0: 50 push %eax + 27d1: 68 e8 50 00 00 push $0x50e8 + 27d6: 6a 01 push $0x1 + 27d8: e8 63 12 00 00 call 3a40 + exit(); + 27dd: e8 f1 10 00 00 call 38d3 + 27e2: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 27e9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +000027f0 : +void rmdot(void) { + 27f0: 55 push %ebp + 27f1: 89 e5 mov %esp,%ebp + 27f3: 83 ec 10 sub $0x10,%esp + printf(1, "rmdot test\n"); + 27f6: 68 27 49 00 00 push $0x4927 + 27fb: 6a 01 push $0x1 + 27fd: e8 3e 12 00 00 call 3a40 + if (mkdir("dots") != 0) { + 2802: c7 04 24 33 49 00 00 movl $0x4933,(%esp) + 2809: e8 55 11 00 00 call 3963 + 280e: 83 c4 10 add $0x10,%esp + 2811: 85 c0 test %eax,%eax + 2813: 0f 85 b0 00 00 00 jne 28c9 + if (chdir("dots") != 0) { + 2819: 83 ec 0c sub $0xc,%esp + 281c: 68 33 49 00 00 push $0x4933 + 2821: e8 e5 10 00 00 call 390b + 2826: 83 c4 10 add $0x10,%esp + 2829: 85 c0 test %eax,%eax + 282b: 0f 85 1d 01 00 00 jne 294e + if (unlink(".") == 0) { + 2831: 83 ec 0c sub $0xc,%esp + 2834: 68 de 45 00 00 push $0x45de + 2839: e8 15 11 00 00 call 3953 + 283e: 83 c4 10 add $0x10,%esp + 2841: 85 c0 test %eax,%eax + 2843: 0f 84 f2 00 00 00 je 293b + if (unlink("..") == 0) { + 2849: 83 ec 0c sub $0xc,%esp + 284c: 68 dd 45 00 00 push $0x45dd + 2851: e8 fd 10 00 00 call 3953 + 2856: 83 c4 10 add $0x10,%esp + 2859: 85 c0 test %eax,%eax + 285b: 0f 84 c7 00 00 00 je 2928 + if (chdir("/") != 0) { + 2861: 83 ec 0c sub $0xc,%esp + 2864: 68 b1 3d 00 00 push $0x3db1 + 2869: e8 9d 10 00 00 call 390b + 286e: 83 c4 10 add $0x10,%esp + 2871: 85 c0 test %eax,%eax + 2873: 0f 85 9c 00 00 00 jne 2915 + if (unlink("dots/.") == 0) { + 2879: 83 ec 0c sub $0xc,%esp + 287c: 68 7b 49 00 00 push $0x497b + 2881: e8 cd 10 00 00 call 3953 + 2886: 83 c4 10 add $0x10,%esp + 2889: 85 c0 test %eax,%eax + 288b: 74 75 je 2902 + if (unlink("dots/..") == 0) { + 288d: 83 ec 0c sub $0xc,%esp + 2890: 68 99 49 00 00 push $0x4999 + 2895: e8 b9 10 00 00 call 3953 + 289a: 83 c4 10 add $0x10,%esp + 289d: 85 c0 test %eax,%eax + 289f: 74 4e je 28ef + if (unlink("dots") != 0) { + 28a1: 83 ec 0c sub $0xc,%esp + 28a4: 68 33 49 00 00 push $0x4933 + 28a9: e8 a5 10 00 00 call 3953 + 28ae: 83 c4 10 add $0x10,%esp + 28b1: 85 c0 test %eax,%eax + 28b3: 75 27 jne 28dc + printf(1, "rmdot ok\n"); + 28b5: 83 ec 08 sub $0x8,%esp + 28b8: 68 ce 49 00 00 push $0x49ce + 28bd: 6a 01 push $0x1 + 28bf: e8 7c 11 00 00 call 3a40 +} + 28c4: 83 c4 10 add $0x10,%esp + 28c7: c9 leave + 28c8: c3 ret + printf(1, "mkdir dots failed\n"); + 28c9: 50 push %eax + 28ca: 50 push %eax + 28cb: 68 38 49 00 00 push $0x4938 + 28d0: 6a 01 push $0x1 + 28d2: e8 69 11 00 00 call 3a40 + exit(); + 28d7: e8 f7 0f 00 00 call 38d3 + printf(1, "unlink dots failed!\n"); + 28dc: 50 push %eax + 28dd: 50 push %eax + 28de: 68 b9 49 00 00 push $0x49b9 + 28e3: 6a 01 push $0x1 + 28e5: e8 56 11 00 00 call 3a40 + exit(); + 28ea: e8 e4 0f 00 00 call 38d3 + printf(1, "unlink dots/.. worked!\n"); + 28ef: 52 push %edx + 28f0: 52 push %edx + 28f1: 68 a1 49 00 00 push $0x49a1 + 28f6: 6a 01 push $0x1 + 28f8: e8 43 11 00 00 call 3a40 + exit(); + 28fd: e8 d1 0f 00 00 call 38d3 + printf(1, "unlink dots/. worked!\n"); + 2902: 51 push %ecx + 2903: 51 push %ecx + 2904: 68 82 49 00 00 push $0x4982 + 2909: 6a 01 push $0x1 + 290b: e8 30 11 00 00 call 3a40 + exit(); + 2910: e8 be 0f 00 00 call 38d3 + printf(1, "chdir / failed\n"); + 2915: 50 push %eax + 2916: 50 push %eax + 2917: 68 b3 3d 00 00 push $0x3db3 + 291c: 6a 01 push $0x1 + 291e: e8 1d 11 00 00 call 3a40 + exit(); + 2923: e8 ab 0f 00 00 call 38d3 + printf(1, "rm .. worked!\n"); + 2928: 50 push %eax + 2929: 50 push %eax + 292a: 68 6c 49 00 00 push $0x496c + 292f: 6a 01 push $0x1 + 2931: e8 0a 11 00 00 call 3a40 + exit(); + 2936: e8 98 0f 00 00 call 38d3 + printf(1, "rm . worked!\n"); + 293b: 50 push %eax + 293c: 50 push %eax + 293d: 68 5e 49 00 00 push $0x495e + 2942: 6a 01 push $0x1 + 2944: e8 f7 10 00 00 call 3a40 + exit(); + 2949: e8 85 0f 00 00 call 38d3 + printf(1, "chdir dots failed\n"); + 294e: 50 push %eax + 294f: 50 push %eax + 2950: 68 4b 49 00 00 push $0x494b + 2955: 6a 01 push $0x1 + 2957: e8 e4 10 00 00 call 3a40 + exit(); + 295c: e8 72 0f 00 00 call 38d3 + 2961: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2968: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 296f: 90 nop + +00002970 : +void dirfile(void) { + 2970: 55 push %ebp + 2971: 89 e5 mov %esp,%ebp + 2973: 53 push %ebx + 2974: 83 ec 0c sub $0xc,%esp + printf(1, "dir vs file\n"); + 2977: 68 d8 49 00 00 push $0x49d8 + 297c: 6a 01 push $0x1 + 297e: e8 bd 10 00 00 call 3a40 + fd = open("dirfile", O_CREATE); + 2983: 5b pop %ebx + 2984: 58 pop %eax + 2985: 68 00 02 00 00 push $0x200 + 298a: 68 e5 49 00 00 push $0x49e5 + 298f: e8 a7 0f 00 00 call 393b + if (fd < 0) { + 2994: 83 c4 10 add $0x10,%esp + 2997: 85 c0 test %eax,%eax + 2999: 0f 88 43 01 00 00 js 2ae2 + close(fd); + 299f: 83 ec 0c sub $0xc,%esp + 29a2: 50 push %eax + 29a3: e8 c3 0f 00 00 call 396b + if (chdir("dirfile") == 0) { + 29a8: c7 04 24 e5 49 00 00 movl $0x49e5,(%esp) + 29af: e8 57 0f 00 00 call 390b + 29b4: 83 c4 10 add $0x10,%esp + 29b7: 85 c0 test %eax,%eax + 29b9: 0f 84 10 01 00 00 je 2acf + fd = open("dirfile/xx", 0); + 29bf: 83 ec 08 sub $0x8,%esp + 29c2: 6a 00 push $0x0 + 29c4: 68 1e 4a 00 00 push $0x4a1e + 29c9: e8 6d 0f 00 00 call 393b + if (fd >= 0) { + 29ce: 83 c4 10 add $0x10,%esp + 29d1: 85 c0 test %eax,%eax + 29d3: 0f 89 e3 00 00 00 jns 2abc + fd = open("dirfile/xx", O_CREATE); + 29d9: 83 ec 08 sub $0x8,%esp + 29dc: 68 00 02 00 00 push $0x200 + 29e1: 68 1e 4a 00 00 push $0x4a1e + 29e6: e8 50 0f 00 00 call 393b + if (fd >= 0) { + 29eb: 83 c4 10 add $0x10,%esp + 29ee: 85 c0 test %eax,%eax + 29f0: 0f 89 c6 00 00 00 jns 2abc + if (mkdir("dirfile/xx") == 0) { + 29f6: 83 ec 0c sub $0xc,%esp + 29f9: 68 1e 4a 00 00 push $0x4a1e + 29fe: e8 60 0f 00 00 call 3963 + 2a03: 83 c4 10 add $0x10,%esp + 2a06: 85 c0 test %eax,%eax + 2a08: 0f 84 46 01 00 00 je 2b54 + if (unlink("dirfile/xx") == 0) { + 2a0e: 83 ec 0c sub $0xc,%esp + 2a11: 68 1e 4a 00 00 push $0x4a1e + 2a16: e8 38 0f 00 00 call 3953 + 2a1b: 83 c4 10 add $0x10,%esp + 2a1e: 85 c0 test %eax,%eax + 2a20: 0f 84 1b 01 00 00 je 2b41 + if (link("README", "dirfile/xx") == 0) { + 2a26: 83 ec 08 sub $0x8,%esp + 2a29: 68 1e 4a 00 00 push $0x4a1e + 2a2e: 68 82 4a 00 00 push $0x4a82 + 2a33: e8 23 0f 00 00 call 395b + 2a38: 83 c4 10 add $0x10,%esp + 2a3b: 85 c0 test %eax,%eax + 2a3d: 0f 84 eb 00 00 00 je 2b2e + if (unlink("dirfile") != 0) { + 2a43: 83 ec 0c sub $0xc,%esp + 2a46: 68 e5 49 00 00 push $0x49e5 + 2a4b: e8 03 0f 00 00 call 3953 + 2a50: 83 c4 10 add $0x10,%esp + 2a53: 85 c0 test %eax,%eax + 2a55: 0f 85 c0 00 00 00 jne 2b1b + fd = open(".", O_RDWR); + 2a5b: 83 ec 08 sub $0x8,%esp + 2a5e: 6a 02 push $0x2 + 2a60: 68 de 45 00 00 push $0x45de + 2a65: e8 d1 0e 00 00 call 393b + if (fd >= 0) { + 2a6a: 83 c4 10 add $0x10,%esp + 2a6d: 85 c0 test %eax,%eax + 2a6f: 0f 89 93 00 00 00 jns 2b08 + fd = open(".", 0); + 2a75: 83 ec 08 sub $0x8,%esp + 2a78: 6a 00 push $0x0 + 2a7a: 68 de 45 00 00 push $0x45de + 2a7f: e8 b7 0e 00 00 call 393b + if (write(fd, "x", 1) > 0) { + 2a84: 83 c4 0c add $0xc,%esp + 2a87: 6a 01 push $0x1 + fd = open(".", 0); + 2a89: 89 c3 mov %eax,%ebx + if (write(fd, "x", 1) > 0) { + 2a8b: 68 c1 46 00 00 push $0x46c1 + 2a90: 50 push %eax + 2a91: e8 ad 0e 00 00 call 3943 + 2a96: 83 c4 10 add $0x10,%esp + 2a99: 85 c0 test %eax,%eax + 2a9b: 7f 58 jg 2af5 + close(fd); + 2a9d: 83 ec 0c sub $0xc,%esp + 2aa0: 53 push %ebx + 2aa1: e8 c5 0e 00 00 call 396b + printf(1, "dir vs file OK\n"); + 2aa6: 58 pop %eax + 2aa7: 5a pop %edx + 2aa8: 68 b5 4a 00 00 push $0x4ab5 + 2aad: 6a 01 push $0x1 + 2aaf: e8 8c 0f 00 00 call 3a40 +} + 2ab4: 8b 5d fc mov -0x4(%ebp),%ebx + 2ab7: 83 c4 10 add $0x10,%esp + 2aba: c9 leave + 2abb: c3 ret + printf(1, "create dirfile/xx succeeded!\n"); + 2abc: 50 push %eax + 2abd: 50 push %eax + 2abe: 68 29 4a 00 00 push $0x4a29 + 2ac3: 6a 01 push $0x1 + 2ac5: e8 76 0f 00 00 call 3a40 + exit(); + 2aca: e8 04 0e 00 00 call 38d3 + printf(1, "chdir dirfile succeeded!\n"); + 2acf: 52 push %edx + 2ad0: 52 push %edx + 2ad1: 68 04 4a 00 00 push $0x4a04 + 2ad6: 6a 01 push $0x1 + 2ad8: e8 63 0f 00 00 call 3a40 + exit(); + 2add: e8 f1 0d 00 00 call 38d3 + printf(1, "create dirfile failed\n"); + 2ae2: 51 push %ecx + 2ae3: 51 push %ecx + 2ae4: 68 ed 49 00 00 push $0x49ed + 2ae9: 6a 01 push $0x1 + 2aeb: e8 50 0f 00 00 call 3a40 + exit(); + 2af0: e8 de 0d 00 00 call 38d3 + printf(1, "write . succeeded!\n"); + 2af5: 51 push %ecx + 2af6: 51 push %ecx + 2af7: 68 a1 4a 00 00 push $0x4aa1 + 2afc: 6a 01 push $0x1 + 2afe: e8 3d 0f 00 00 call 3a40 + exit(); + 2b03: e8 cb 0d 00 00 call 38d3 + printf(1, "open . for writing succeeded!\n"); + 2b08: 53 push %ebx + 2b09: 53 push %ebx + 2b0a: 68 98 52 00 00 push $0x5298 + 2b0f: 6a 01 push $0x1 + 2b11: e8 2a 0f 00 00 call 3a40 + exit(); + 2b16: e8 b8 0d 00 00 call 38d3 + printf(1, "unlink dirfile failed!\n"); + 2b1b: 50 push %eax + 2b1c: 50 push %eax + 2b1d: 68 89 4a 00 00 push $0x4a89 + 2b22: 6a 01 push $0x1 + 2b24: e8 17 0f 00 00 call 3a40 + exit(); + 2b29: e8 a5 0d 00 00 call 38d3 + printf(1, "link to dirfile/xx succeeded!\n"); + 2b2e: 50 push %eax + 2b2f: 50 push %eax + 2b30: 68 78 52 00 00 push $0x5278 + 2b35: 6a 01 push $0x1 + 2b37: e8 04 0f 00 00 call 3a40 + exit(); + 2b3c: e8 92 0d 00 00 call 38d3 + printf(1, "unlink dirfile/xx succeeded!\n"); + 2b41: 50 push %eax + 2b42: 50 push %eax + 2b43: 68 64 4a 00 00 push $0x4a64 + 2b48: 6a 01 push $0x1 + 2b4a: e8 f1 0e 00 00 call 3a40 + exit(); + 2b4f: e8 7f 0d 00 00 call 38d3 + printf(1, "mkdir dirfile/xx succeeded!\n"); + 2b54: 50 push %eax + 2b55: 50 push %eax + 2b56: 68 47 4a 00 00 push $0x4a47 + 2b5b: 6a 01 push $0x1 + 2b5d: e8 de 0e 00 00 call 3a40 + exit(); + 2b62: e8 6c 0d 00 00 call 38d3 + 2b67: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2b6e: 66 90 xchg %ax,%ax + +00002b70 : +void iref(void) { + 2b70: 55 push %ebp + 2b71: 89 e5 mov %esp,%ebp + 2b73: 53 push %ebx + printf(1, "empty file name\n"); + 2b74: bb 33 00 00 00 mov $0x33,%ebx +void iref(void) { + 2b79: 83 ec 0c sub $0xc,%esp + printf(1, "empty file name\n"); + 2b7c: 68 c5 4a 00 00 push $0x4ac5 + 2b81: 6a 01 push $0x1 + 2b83: e8 b8 0e 00 00 call 3a40 + 2b88: 83 c4 10 add $0x10,%esp + 2b8b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 2b8f: 90 nop + if (mkdir("irefd") != 0) { + 2b90: 83 ec 0c sub $0xc,%esp + 2b93: 68 d6 4a 00 00 push $0x4ad6 + 2b98: e8 c6 0d 00 00 call 3963 + 2b9d: 83 c4 10 add $0x10,%esp + 2ba0: 85 c0 test %eax,%eax + 2ba2: 0f 85 bb 00 00 00 jne 2c63 + if (chdir("irefd") != 0) { + 2ba8: 83 ec 0c sub $0xc,%esp + 2bab: 68 d6 4a 00 00 push $0x4ad6 + 2bb0: e8 56 0d 00 00 call 390b + 2bb5: 83 c4 10 add $0x10,%esp + 2bb8: 85 c0 test %eax,%eax + 2bba: 0f 85 b7 00 00 00 jne 2c77 + mkdir(""); + 2bc0: 83 ec 0c sub $0xc,%esp + 2bc3: 68 8b 41 00 00 push $0x418b + 2bc8: e8 96 0d 00 00 call 3963 + link("README", ""); + 2bcd: 59 pop %ecx + 2bce: 58 pop %eax + 2bcf: 68 8b 41 00 00 push $0x418b + 2bd4: 68 82 4a 00 00 push $0x4a82 + 2bd9: e8 7d 0d 00 00 call 395b + fd = open("", O_CREATE); + 2bde: 58 pop %eax + 2bdf: 5a pop %edx + 2be0: 68 00 02 00 00 push $0x200 + 2be5: 68 8b 41 00 00 push $0x418b + 2bea: e8 4c 0d 00 00 call 393b + if (fd >= 0) { + 2bef: 83 c4 10 add $0x10,%esp + 2bf2: 85 c0 test %eax,%eax + 2bf4: 78 0c js 2c02 + close(fd); + 2bf6: 83 ec 0c sub $0xc,%esp + 2bf9: 50 push %eax + 2bfa: e8 6c 0d 00 00 call 396b + 2bff: 83 c4 10 add $0x10,%esp + fd = open("xx", O_CREATE); + 2c02: 83 ec 08 sub $0x8,%esp + 2c05: 68 00 02 00 00 push $0x200 + 2c0a: 68 c0 46 00 00 push $0x46c0 + 2c0f: e8 27 0d 00 00 call 393b + if (fd >= 0) { + 2c14: 83 c4 10 add $0x10,%esp + 2c17: 85 c0 test %eax,%eax + 2c19: 78 0c js 2c27 + close(fd); + 2c1b: 83 ec 0c sub $0xc,%esp + 2c1e: 50 push %eax + 2c1f: e8 47 0d 00 00 call 396b + 2c24: 83 c4 10 add $0x10,%esp + unlink("xx"); + 2c27: 83 ec 0c sub $0xc,%esp + 2c2a: 68 c0 46 00 00 push $0x46c0 + 2c2f: e8 1f 0d 00 00 call 3953 + for (i = 0; i < 50 + 1; i++) { + 2c34: 83 c4 10 add $0x10,%esp + 2c37: 83 eb 01 sub $0x1,%ebx + 2c3a: 0f 85 50 ff ff ff jne 2b90 + chdir("/"); + 2c40: 83 ec 0c sub $0xc,%esp + 2c43: 68 b1 3d 00 00 push $0x3db1 + 2c48: e8 be 0c 00 00 call 390b + printf(1, "empty file name OK\n"); + 2c4d: 58 pop %eax + 2c4e: 5a pop %edx + 2c4f: 68 04 4b 00 00 push $0x4b04 + 2c54: 6a 01 push $0x1 + 2c56: e8 e5 0d 00 00 call 3a40 +} + 2c5b: 8b 5d fc mov -0x4(%ebp),%ebx + 2c5e: 83 c4 10 add $0x10,%esp + 2c61: c9 leave + 2c62: c3 ret + printf(1, "mkdir irefd failed\n"); + 2c63: 83 ec 08 sub $0x8,%esp + 2c66: 68 dc 4a 00 00 push $0x4adc + 2c6b: 6a 01 push $0x1 + 2c6d: e8 ce 0d 00 00 call 3a40 + exit(); + 2c72: e8 5c 0c 00 00 call 38d3 + printf(1, "chdir irefd failed\n"); + 2c77: 83 ec 08 sub $0x8,%esp + 2c7a: 68 f0 4a 00 00 push $0x4af0 + 2c7f: 6a 01 push $0x1 + 2c81: e8 ba 0d 00 00 call 3a40 + exit(); + 2c86: e8 48 0c 00 00 call 38d3 + 2c8b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 2c8f: 90 nop + +00002c90 : +void forktest(void) { + 2c90: 55 push %ebp + 2c91: 89 e5 mov %esp,%ebp + 2c93: 53 push %ebx + for (n = 0; n < 1000; n++) { + 2c94: 31 db xor %ebx,%ebx +void forktest(void) { + 2c96: 83 ec 0c sub $0xc,%esp + printf(1, "fork test\n"); + 2c99: 68 18 4b 00 00 push $0x4b18 + 2c9e: 6a 01 push $0x1 + 2ca0: e8 9b 0d 00 00 call 3a40 + 2ca5: 83 c4 10 add $0x10,%esp + 2ca8: eb 13 jmp 2cbd + 2caa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (pid == 0) { + 2cb0: 74 4a je 2cfc + for (n = 0; n < 1000; n++) { + 2cb2: 83 c3 01 add $0x1,%ebx + 2cb5: 81 fb e8 03 00 00 cmp $0x3e8,%ebx + 2cbb: 74 6b je 2d28 + pid = fork(); + 2cbd: e8 09 0c 00 00 call 38cb + if (pid < 0) { + 2cc2: 85 c0 test %eax,%eax + 2cc4: 79 ea jns 2cb0 + for (; n > 0; n--) { + 2cc6: 85 db test %ebx,%ebx + 2cc8: 74 14 je 2cde + 2cca: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (wait() < 0) { + 2cd0: e8 06 0c 00 00 call 38db + 2cd5: 85 c0 test %eax,%eax + 2cd7: 78 28 js 2d01 + for (; n > 0; n--) { + 2cd9: 83 eb 01 sub $0x1,%ebx + 2cdc: 75 f2 jne 2cd0 + if (wait() != -1) { + 2cde: e8 f8 0b 00 00 call 38db + 2ce3: 83 f8 ff cmp $0xffffffff,%eax + 2ce6: 75 2d jne 2d15 + printf(1, "fork test OK\n"); + 2ce8: 83 ec 08 sub $0x8,%esp + 2ceb: 68 4a 4b 00 00 push $0x4b4a + 2cf0: 6a 01 push $0x1 + 2cf2: e8 49 0d 00 00 call 3a40 +} + 2cf7: 8b 5d fc mov -0x4(%ebp),%ebx + 2cfa: c9 leave + 2cfb: c3 ret + exit(); + 2cfc: e8 d2 0b 00 00 call 38d3 + printf(1, "wait stopped early\n"); + 2d01: 83 ec 08 sub $0x8,%esp + 2d04: 68 23 4b 00 00 push $0x4b23 + 2d09: 6a 01 push $0x1 + 2d0b: e8 30 0d 00 00 call 3a40 + exit(); + 2d10: e8 be 0b 00 00 call 38d3 + printf(1, "wait got too many\n"); + 2d15: 52 push %edx + 2d16: 52 push %edx + 2d17: 68 37 4b 00 00 push $0x4b37 + 2d1c: 6a 01 push $0x1 + 2d1e: e8 1d 0d 00 00 call 3a40 + exit(); + 2d23: e8 ab 0b 00 00 call 38d3 + printf(1, "fork claimed to work 1000 times!\n"); + 2d28: 50 push %eax + 2d29: 50 push %eax + 2d2a: 68 b8 52 00 00 push $0x52b8 + 2d2f: 6a 01 push $0x1 + 2d31: e8 0a 0d 00 00 call 3a40 + exit(); + 2d36: e8 98 0b 00 00 call 38d3 + 2d3b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 2d3f: 90 nop + +00002d40 : +void sbrktest(void) { + 2d40: 55 push %ebp + 2d41: 89 e5 mov %esp,%ebp + 2d43: 57 push %edi + 2d44: 56 push %esi + for (i = 0; i < 5000; i++) { + 2d45: 31 f6 xor %esi,%esi +void sbrktest(void) { + 2d47: 53 push %ebx + 2d48: 83 ec 64 sub $0x64,%esp + printf(stdout, "sbrk test\n"); + 2d4b: 68 58 4b 00 00 push $0x4b58 + 2d50: ff 35 58 5e 00 00 push 0x5e58 + 2d56: e8 e5 0c 00 00 call 3a40 + oldbrk = sbrk(0); + 2d5b: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 2d62: e8 bc 0b 00 00 call 3923 + a = sbrk(0); + 2d67: c7 04 24 00 00 00 00 movl $0x0,(%esp) + oldbrk = sbrk(0); + 2d6e: 89 45 a4 mov %eax,-0x5c(%ebp) + a = sbrk(0); + 2d71: e8 ad 0b 00 00 call 3923 + 2d76: 83 c4 10 add $0x10,%esp + 2d79: 89 c3 mov %eax,%ebx + for (i = 0; i < 5000; i++) { + 2d7b: eb 05 jmp 2d82 + 2d7d: 8d 76 00 lea 0x0(%esi),%esi + a = b + 1; + 2d80: 89 c3 mov %eax,%ebx + b = sbrk(1); + 2d82: 83 ec 0c sub $0xc,%esp + 2d85: 6a 01 push $0x1 + 2d87: e8 97 0b 00 00 call 3923 + if (b != a) { + 2d8c: 83 c4 10 add $0x10,%esp + 2d8f: 39 d8 cmp %ebx,%eax + 2d91: 0f 85 9c 02 00 00 jne 3033 + for (i = 0; i < 5000; i++) { + 2d97: 83 c6 01 add $0x1,%esi + *b = 1; + 2d9a: c6 03 01 movb $0x1,(%ebx) + a = b + 1; + 2d9d: 8d 43 01 lea 0x1(%ebx),%eax + for (i = 0; i < 5000; i++) { + 2da0: 81 fe 88 13 00 00 cmp $0x1388,%esi + 2da6: 75 d8 jne 2d80 + pid = fork(); + 2da8: e8 1e 0b 00 00 call 38cb + 2dad: 89 c6 mov %eax,%esi + if (pid < 0) { + 2daf: 85 c0 test %eax,%eax + 2db1: 0f 88 02 03 00 00 js 30b9 + c = sbrk(1); + 2db7: 83 ec 0c sub $0xc,%esp + if (c != a + 1) { + 2dba: 83 c3 02 add $0x2,%ebx + c = sbrk(1); + 2dbd: 6a 01 push $0x1 + 2dbf: e8 5f 0b 00 00 call 3923 + c = sbrk(1); + 2dc4: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 2dcb: e8 53 0b 00 00 call 3923 + if (c != a + 1) { + 2dd0: 83 c4 10 add $0x10,%esp + 2dd3: 39 c3 cmp %eax,%ebx + 2dd5: 0f 85 3b 03 00 00 jne 3116 + if (pid == 0) { + 2ddb: 85 f6 test %esi,%esi + 2ddd: 0f 84 2e 03 00 00 je 3111 + wait(); + 2de3: e8 f3 0a 00 00 call 38db + a = sbrk(0); + 2de8: 83 ec 0c sub $0xc,%esp + 2deb: 6a 00 push $0x0 + 2ded: e8 31 0b 00 00 call 3923 + 2df2: 89 c3 mov %eax,%ebx + amt = (BIG) -(uint)a; + 2df4: b8 00 00 40 06 mov $0x6400000,%eax + 2df9: 29 d8 sub %ebx,%eax + p = sbrk(amt); + 2dfb: 89 04 24 mov %eax,(%esp) + 2dfe: e8 20 0b 00 00 call 3923 + if (p != a) { + 2e03: 83 c4 10 add $0x10,%esp + 2e06: 39 c3 cmp %eax,%ebx + 2e08: 0f 85 94 02 00 00 jne 30a2 + a = sbrk(0); + 2e0e: 83 ec 0c sub $0xc,%esp + *lastaddr = 99; + 2e11: c6 05 ff ff 3f 06 63 movb $0x63,0x63fffff + a = sbrk(0); + 2e18: 6a 00 push $0x0 + 2e1a: e8 04 0b 00 00 call 3923 + c = sbrk(-4096); + 2e1f: c7 04 24 00 f0 ff ff movl $0xfffff000,(%esp) + a = sbrk(0); + 2e26: 89 c3 mov %eax,%ebx + c = sbrk(-4096); + 2e28: e8 f6 0a 00 00 call 3923 + if (c == (char*)0xffffffff) { + 2e2d: 83 c4 10 add $0x10,%esp + 2e30: 83 f8 ff cmp $0xffffffff,%eax + 2e33: 0f 84 22 03 00 00 je 315b + c = sbrk(0); + 2e39: 83 ec 0c sub $0xc,%esp + 2e3c: 6a 00 push $0x0 + 2e3e: e8 e0 0a 00 00 call 3923 + if (c != a - 4096) { + 2e43: 8d 93 00 f0 ff ff lea -0x1000(%ebx),%edx + 2e49: 83 c4 10 add $0x10,%esp + 2e4c: 39 d0 cmp %edx,%eax + 2e4e: 0f 85 f0 02 00 00 jne 3144 + a = sbrk(0); + 2e54: 83 ec 0c sub $0xc,%esp + 2e57: 6a 00 push $0x0 + 2e59: e8 c5 0a 00 00 call 3923 + c = sbrk(4096); + 2e5e: c7 04 24 00 10 00 00 movl $0x1000,(%esp) + a = sbrk(0); + 2e65: 89 c3 mov %eax,%ebx + c = sbrk(4096); + 2e67: e8 b7 0a 00 00 call 3923 + if (c != a || sbrk(0) != a + 4096) { + 2e6c: 83 c4 10 add $0x10,%esp + c = sbrk(4096); + 2e6f: 89 c6 mov %eax,%esi + if (c != a || sbrk(0) != a + 4096) { + 2e71: 39 c3 cmp %eax,%ebx + 2e73: 0f 85 b4 02 00 00 jne 312d + 2e79: 83 ec 0c sub $0xc,%esp + 2e7c: 6a 00 push $0x0 + 2e7e: e8 a0 0a 00 00 call 3923 + 2e83: 8d 93 00 10 00 00 lea 0x1000(%ebx),%edx + 2e89: 83 c4 10 add $0x10,%esp + 2e8c: 39 c2 cmp %eax,%edx + 2e8e: 0f 85 99 02 00 00 jne 312d + if (*lastaddr == 99) { + 2e94: 80 3d ff ff 3f 06 63 cmpb $0x63,0x63fffff + 2e9b: 0f 84 2f 02 00 00 je 30d0 + a = sbrk(0); + 2ea1: 83 ec 0c sub $0xc,%esp + 2ea4: 6a 00 push $0x0 + 2ea6: e8 78 0a 00 00 call 3923 + c = sbrk(-(sbrk(0) - oldbrk)); + 2eab: c7 04 24 00 00 00 00 movl $0x0,(%esp) + a = sbrk(0); + 2eb2: 89 c3 mov %eax,%ebx + c = sbrk(-(sbrk(0) - oldbrk)); + 2eb4: e8 6a 0a 00 00 call 3923 + 2eb9: 89 c2 mov %eax,%edx + 2ebb: 8b 45 a4 mov -0x5c(%ebp),%eax + 2ebe: 29 d0 sub %edx,%eax + 2ec0: 89 04 24 mov %eax,(%esp) + 2ec3: e8 5b 0a 00 00 call 3923 + if (c != a) { + 2ec8: 83 c4 10 add $0x10,%esp + 2ecb: 39 c3 cmp %eax,%ebx + 2ecd: 0f 85 b8 01 00 00 jne 308b + for (a = (char*)(KERNBASE); a < (char*) (KERNBASE + 2000000); a += 50000) { + 2ed3: bb 00 00 00 80 mov $0x80000000,%ebx + 2ed8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 2edf: 90 nop + ppid = getpid(); + 2ee0: e8 36 0a 00 00 call 391b + 2ee5: 89 c6 mov %eax,%esi + pid = fork(); + 2ee7: e8 df 09 00 00 call 38cb + if (pid < 0) { + 2eec: 85 c0 test %eax,%eax + 2eee: 0f 88 5d 01 00 00 js 3051 + if (pid == 0) { + 2ef4: 0f 84 6f 01 00 00 je 3069 + wait(); + 2efa: e8 dc 09 00 00 call 38db + for (a = (char*)(KERNBASE); a < (char*) (KERNBASE + 2000000); a += 50000) { + 2eff: 81 c3 50 c3 00 00 add $0xc350,%ebx + 2f05: 81 fb 80 84 1e 80 cmp $0x801e8480,%ebx + 2f0b: 75 d3 jne 2ee0 + if (pipe(fds) != 0) { + 2f0d: 83 ec 0c sub $0xc,%esp + 2f10: 8d 45 b8 lea -0x48(%ebp),%eax + 2f13: 50 push %eax + 2f14: e8 ca 09 00 00 call 38e3 + 2f19: 83 c4 10 add $0x10,%esp + 2f1c: 85 c0 test %eax,%eax + 2f1e: 0f 85 da 01 00 00 jne 30fe + 2f24: 8d 5d c0 lea -0x40(%ebp),%ebx + 2f27: 8d 75 e8 lea -0x18(%ebp),%esi + 2f2a: 89 df mov %ebx,%edi + 2f2c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if ((pids[i] = fork()) == 0) { + 2f30: e8 96 09 00 00 call 38cb + 2f35: 89 07 mov %eax,(%edi) + 2f37: 85 c0 test %eax,%eax + 2f39: 0f 84 91 00 00 00 je 2fd0 + if (pids[i] != -1) { + 2f3f: 83 f8 ff cmp $0xffffffff,%eax + 2f42: 74 14 je 2f58 + read(fds[0], &scratch, 1); + 2f44: 83 ec 04 sub $0x4,%esp + 2f47: 8d 45 b7 lea -0x49(%ebp),%eax + 2f4a: 6a 01 push $0x1 + 2f4c: 50 push %eax + 2f4d: ff 75 b8 push -0x48(%ebp) + 2f50: e8 96 09 00 00 call 38eb + 2f55: 83 c4 10 add $0x10,%esp + for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { + 2f58: 83 c7 04 add $0x4,%edi + 2f5b: 39 f7 cmp %esi,%edi + 2f5d: 75 d1 jne 2f30 + c = sbrk(4096); + 2f5f: 83 ec 0c sub $0xc,%esp + 2f62: 68 00 10 00 00 push $0x1000 + 2f67: e8 b7 09 00 00 call 3923 + 2f6c: 83 c4 10 add $0x10,%esp + 2f6f: 89 c7 mov %eax,%edi + for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { + 2f71: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + if (pids[i] == -1) { + 2f78: 8b 03 mov (%ebx),%eax + 2f7a: 83 f8 ff cmp $0xffffffff,%eax + 2f7d: 74 11 je 2f90 + kill(pids[i]); + 2f7f: 83 ec 0c sub $0xc,%esp + 2f82: 50 push %eax + 2f83: e8 6b 09 00 00 call 38f3 + wait(); + 2f88: e8 4e 09 00 00 call 38db + 2f8d: 83 c4 10 add $0x10,%esp + for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { + 2f90: 83 c3 04 add $0x4,%ebx + 2f93: 39 de cmp %ebx,%esi + 2f95: 75 e1 jne 2f78 + if (c == (char*)0xffffffff) { + 2f97: 83 ff ff cmp $0xffffffff,%edi + 2f9a: 0f 84 47 01 00 00 je 30e7 + if (sbrk(0) > oldbrk) { + 2fa0: 83 ec 0c sub $0xc,%esp + 2fa3: 6a 00 push $0x0 + 2fa5: e8 79 09 00 00 call 3923 + 2faa: 83 c4 10 add $0x10,%esp + 2fad: 39 45 a4 cmp %eax,-0x5c(%ebp) + 2fb0: 72 60 jb 3012 + printf(stdout, "sbrk test OK\n"); + 2fb2: 83 ec 08 sub $0x8,%esp + 2fb5: 68 00 4c 00 00 push $0x4c00 + 2fba: ff 35 58 5e 00 00 push 0x5e58 + 2fc0: e8 7b 0a 00 00 call 3a40 +} + 2fc5: 83 c4 10 add $0x10,%esp + 2fc8: 8d 65 f4 lea -0xc(%ebp),%esp + 2fcb: 5b pop %ebx + 2fcc: 5e pop %esi + 2fcd: 5f pop %edi + 2fce: 5d pop %ebp + 2fcf: c3 ret + sbrk(BIG - (uint)sbrk(0)); + 2fd0: 83 ec 0c sub $0xc,%esp + 2fd3: 6a 00 push $0x0 + 2fd5: e8 49 09 00 00 call 3923 + 2fda: 89 c2 mov %eax,%edx + 2fdc: b8 00 00 40 06 mov $0x6400000,%eax + 2fe1: 29 d0 sub %edx,%eax + 2fe3: 89 04 24 mov %eax,(%esp) + 2fe6: e8 38 09 00 00 call 3923 + write(fds[1], "x", 1); + 2feb: 83 c4 0c add $0xc,%esp + 2fee: 6a 01 push $0x1 + 2ff0: 68 c1 46 00 00 push $0x46c1 + 2ff5: ff 75 bc push -0x44(%ebp) + 2ff8: e8 46 09 00 00 call 3943 + 2ffd: 83 c4 10 add $0x10,%esp + for (;;) { sleep(1000); + 3000: 83 ec 0c sub $0xc,%esp + 3003: 68 e8 03 00 00 push $0x3e8 + 3008: e8 1e 09 00 00 call 392b + 300d: 83 c4 10 add $0x10,%esp + 3010: eb ee jmp 3000 + sbrk(-(sbrk(0) - oldbrk)); + 3012: 83 ec 0c sub $0xc,%esp + 3015: 6a 00 push $0x0 + 3017: e8 07 09 00 00 call 3923 + 301c: 89 c2 mov %eax,%edx + 301e: 8b 45 a4 mov -0x5c(%ebp),%eax + 3021: 29 d0 sub %edx,%eax + 3023: 89 04 24 mov %eax,(%esp) + 3026: e8 f8 08 00 00 call 3923 + 302b: 83 c4 10 add $0x10,%esp + 302e: e9 7f ff ff ff jmp 2fb2 + printf(stdout, "sbrk test failed %d %x %x\n", i, a, b); + 3033: 83 ec 0c sub $0xc,%esp + 3036: 50 push %eax + 3037: 53 push %ebx + 3038: 56 push %esi + 3039: 68 63 4b 00 00 push $0x4b63 + 303e: ff 35 58 5e 00 00 push 0x5e58 + 3044: e8 f7 09 00 00 call 3a40 + exit(); + 3049: 83 c4 20 add $0x20,%esp + 304c: e8 82 08 00 00 call 38d3 + printf(stdout, "fork failed\n"); + 3051: 83 ec 08 sub $0x8,%esp + 3054: 68 a9 4c 00 00 push $0x4ca9 + 3059: ff 35 58 5e 00 00 push 0x5e58 + 305f: e8 dc 09 00 00 call 3a40 + exit(); + 3064: e8 6a 08 00 00 call 38d3 + printf(stdout, "oops could read %x = %x\n", a, *a); + 3069: 0f be 03 movsbl (%ebx),%eax + 306c: 50 push %eax + 306d: 53 push %ebx + 306e: 68 cc 4b 00 00 push $0x4bcc + 3073: ff 35 58 5e 00 00 push 0x5e58 + 3079: e8 c2 09 00 00 call 3a40 + kill(ppid); + 307e: 89 34 24 mov %esi,(%esp) + 3081: e8 6d 08 00 00 call 38f3 + exit(); + 3086: e8 48 08 00 00 call 38d3 + printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c); + 308b: 50 push %eax + 308c: 53 push %ebx + 308d: 68 ac 53 00 00 push $0x53ac + 3092: ff 35 58 5e 00 00 push 0x5e58 + 3098: e8 a3 09 00 00 call 3a40 + exit(); + 309d: e8 31 08 00 00 call 38d3 + printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); + 30a2: 56 push %esi + 30a3: 56 push %esi + 30a4: 68 dc 52 00 00 push $0x52dc + 30a9: ff 35 58 5e 00 00 push 0x5e58 + 30af: e8 8c 09 00 00 call 3a40 + exit(); + 30b4: e8 1a 08 00 00 call 38d3 + printf(stdout, "sbrk test fork failed\n"); + 30b9: 50 push %eax + 30ba: 50 push %eax + 30bb: 68 7e 4b 00 00 push $0x4b7e + 30c0: ff 35 58 5e 00 00 push 0x5e58 + 30c6: e8 75 09 00 00 call 3a40 + exit(); + 30cb: e8 03 08 00 00 call 38d3 + printf(stdout, "sbrk de-allocation didn't really deallocate\n"); + 30d0: 51 push %ecx + 30d1: 51 push %ecx + 30d2: 68 7c 53 00 00 push $0x537c + 30d7: ff 35 58 5e 00 00 push 0x5e58 + 30dd: e8 5e 09 00 00 call 3a40 + exit(); + 30e2: e8 ec 07 00 00 call 38d3 + printf(stdout, "failed sbrk leaked memory\n"); + 30e7: 50 push %eax + 30e8: 50 push %eax + 30e9: 68 e5 4b 00 00 push $0x4be5 + 30ee: ff 35 58 5e 00 00 push 0x5e58 + 30f4: e8 47 09 00 00 call 3a40 + exit(); + 30f9: e8 d5 07 00 00 call 38d3 + printf(1, "pipe() failed\n"); + 30fe: 52 push %edx + 30ff: 52 push %edx + 3100: 68 a1 40 00 00 push $0x40a1 + 3105: 6a 01 push $0x1 + 3107: e8 34 09 00 00 call 3a40 + exit(); + 310c: e8 c2 07 00 00 call 38d3 + exit(); + 3111: e8 bd 07 00 00 call 38d3 + printf(stdout, "sbrk test failed post-fork\n"); + 3116: 57 push %edi + 3117: 57 push %edi + 3118: 68 95 4b 00 00 push $0x4b95 + 311d: ff 35 58 5e 00 00 push 0x5e58 + 3123: e8 18 09 00 00 call 3a40 + exit(); + 3128: e8 a6 07 00 00 call 38d3 + printf(stdout, "sbrk re-allocation failed, a %x c %x\n", a, c); + 312d: 56 push %esi + 312e: 53 push %ebx + 312f: 68 54 53 00 00 push $0x5354 + 3134: ff 35 58 5e 00 00 push 0x5e58 + 313a: e8 01 09 00 00 call 3a40 + exit(); + 313f: e8 8f 07 00 00 call 38d3 + printf(stdout, "sbrk deallocation produced wrong address, a %x c %x\n", a, c); + 3144: 50 push %eax + 3145: 53 push %ebx + 3146: 68 1c 53 00 00 push $0x531c + 314b: ff 35 58 5e 00 00 push 0x5e58 + 3151: e8 ea 08 00 00 call 3a40 + exit(); + 3156: e8 78 07 00 00 call 38d3 + printf(stdout, "sbrk could not deallocate\n"); + 315b: 53 push %ebx + 315c: 53 push %ebx + 315d: 68 b1 4b 00 00 push $0x4bb1 + 3162: ff 35 58 5e 00 00 push 0x5e58 + 3168: e8 d3 08 00 00 call 3a40 + exit(); + 316d: e8 61 07 00 00 call 38d3 + 3172: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3179: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00003180 : +} + 3180: c3 ret + 3181: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3188: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 318f: 90 nop + +00003190 : +void validatetest(void) { + 3190: 55 push %ebp + 3191: 89 e5 mov %esp,%ebp + 3193: 56 push %esi + for (p = 0; p <= (uint)hi; p += 4096) { + 3194: 31 f6 xor %esi,%esi +void validatetest(void) { + 3196: 53 push %ebx + printf(stdout, "validate test\n"); + 3197: 83 ec 08 sub $0x8,%esp + 319a: 68 0e 4c 00 00 push $0x4c0e + 319f: ff 35 58 5e 00 00 push 0x5e58 + 31a5: e8 96 08 00 00 call 3a40 + 31aa: 83 c4 10 add $0x10,%esp + 31ad: 8d 76 00 lea 0x0(%esi),%esi + if ((pid = fork()) == 0) { + 31b0: e8 16 07 00 00 call 38cb + 31b5: 89 c3 mov %eax,%ebx + 31b7: 85 c0 test %eax,%eax + 31b9: 74 63 je 321e + sleep(0); + 31bb: 83 ec 0c sub $0xc,%esp + 31be: 6a 00 push $0x0 + 31c0: e8 66 07 00 00 call 392b + sleep(0); + 31c5: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 31cc: e8 5a 07 00 00 call 392b + kill(pid); + 31d1: 89 1c 24 mov %ebx,(%esp) + 31d4: e8 1a 07 00 00 call 38f3 + wait(); + 31d9: e8 fd 06 00 00 call 38db + if (link("nosuchfile", (char*)p) != -1) { + 31de: 58 pop %eax + 31df: 5a pop %edx + 31e0: 56 push %esi + 31e1: 68 1d 4c 00 00 push $0x4c1d + 31e6: e8 70 07 00 00 call 395b + 31eb: 83 c4 10 add $0x10,%esp + 31ee: 83 f8 ff cmp $0xffffffff,%eax + 31f1: 75 30 jne 3223 + for (p = 0; p <= (uint)hi; p += 4096) { + 31f3: 81 c6 00 10 00 00 add $0x1000,%esi + 31f9: 81 fe 00 40 11 00 cmp $0x114000,%esi + 31ff: 75 af jne 31b0 + printf(stdout, "validate ok\n"); + 3201: 83 ec 08 sub $0x8,%esp + 3204: 68 41 4c 00 00 push $0x4c41 + 3209: ff 35 58 5e 00 00 push 0x5e58 + 320f: e8 2c 08 00 00 call 3a40 +} + 3214: 83 c4 10 add $0x10,%esp + 3217: 8d 65 f8 lea -0x8(%ebp),%esp + 321a: 5b pop %ebx + 321b: 5e pop %esi + 321c: 5d pop %ebp + 321d: c3 ret + exit(); + 321e: e8 b0 06 00 00 call 38d3 + printf(stdout, "link should not succeed\n"); + 3223: 83 ec 08 sub $0x8,%esp + 3226: 68 28 4c 00 00 push $0x4c28 + 322b: ff 35 58 5e 00 00 push 0x5e58 + 3231: e8 0a 08 00 00 call 3a40 + exit(); + 3236: e8 98 06 00 00 call 38d3 + 323b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 323f: 90 nop + +00003240 : +void bsstest(void) { + 3240: 55 push %ebp + 3241: 89 e5 mov %esp,%ebp + 3243: 83 ec 10 sub $0x10,%esp + printf(stdout, "bss test\n"); + 3246: 68 4e 4c 00 00 push $0x4c4e + 324b: ff 35 58 5e 00 00 push 0x5e58 + 3251: e8 ea 07 00 00 call 3a40 + 3256: 83 c4 10 add $0x10,%esp + for (i = 0; i < sizeof(uninit); i++) { + 3259: 31 c0 xor %eax,%eax + 325b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 325f: 90 nop + if (uninit[i] != '\0') { + 3260: 80 b8 80 5e 00 00 00 cmpb $0x0,0x5e80(%eax) + 3267: 75 22 jne 328b + for (i = 0; i < sizeof(uninit); i++) { + 3269: 83 c0 01 add $0x1,%eax + 326c: 3d 10 27 00 00 cmp $0x2710,%eax + 3271: 75 ed jne 3260 + printf(stdout, "bss test ok\n"); + 3273: 83 ec 08 sub $0x8,%esp + 3276: 68 69 4c 00 00 push $0x4c69 + 327b: ff 35 58 5e 00 00 push 0x5e58 + 3281: e8 ba 07 00 00 call 3a40 +} + 3286: 83 c4 10 add $0x10,%esp + 3289: c9 leave + 328a: c3 ret + printf(stdout, "bss test failed\n"); + 328b: 83 ec 08 sub $0x8,%esp + 328e: 68 58 4c 00 00 push $0x4c58 + 3293: ff 35 58 5e 00 00 push 0x5e58 + 3299: e8 a2 07 00 00 call 3a40 + exit(); + 329e: e8 30 06 00 00 call 38d3 + 32a3: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 32aa: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +000032b0 : +void bigargtest(void) { + 32b0: 55 push %ebp + 32b1: 89 e5 mov %esp,%ebp + 32b3: 83 ec 14 sub $0x14,%esp + unlink("bigarg-ok"); + 32b6: 68 76 4c 00 00 push $0x4c76 + 32bb: e8 93 06 00 00 call 3953 + pid = fork(); + 32c0: e8 06 06 00 00 call 38cb + if (pid == 0) { + 32c5: 83 c4 10 add $0x10,%esp + 32c8: 85 c0 test %eax,%eax + 32ca: 74 44 je 3310 + else if (pid < 0) { + 32cc: 0f 88 c5 00 00 00 js 3397 + wait(); + 32d2: e8 04 06 00 00 call 38db + fd = open("bigarg-ok", 0); + 32d7: 83 ec 08 sub $0x8,%esp + 32da: 6a 00 push $0x0 + 32dc: 68 76 4c 00 00 push $0x4c76 + 32e1: e8 55 06 00 00 call 393b + if (fd < 0) { + 32e6: 83 c4 10 add $0x10,%esp + 32e9: 85 c0 test %eax,%eax + 32eb: 0f 88 8f 00 00 00 js 3380 + close(fd); + 32f1: 83 ec 0c sub $0xc,%esp + 32f4: 50 push %eax + 32f5: e8 71 06 00 00 call 396b + unlink("bigarg-ok"); + 32fa: c7 04 24 76 4c 00 00 movl $0x4c76,(%esp) + 3301: e8 4d 06 00 00 call 3953 +} + 3306: 83 c4 10 add $0x10,%esp + 3309: c9 leave + 330a: c3 ret + 330b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 330f: 90 nop + args[i] = "bigargs test: failed\n "; + 3310: c7 04 85 a0 a5 00 00 movl $0x53d0,0xa5a0(,%eax,4) + 3317: d0 53 00 00 + for (i = 0; i < MAXARG - 1; i++) { + 331b: 83 c0 01 add $0x1,%eax + 331e: 83 f8 1f cmp $0x1f,%eax + 3321: 75 ed jne 3310 + printf(stdout, "bigarg test\n"); + 3323: 51 push %ecx + 3324: 51 push %ecx + 3325: 68 80 4c 00 00 push $0x4c80 + 332a: ff 35 58 5e 00 00 push 0x5e58 + args[MAXARG - 1] = 0; + 3330: c7 05 1c a6 00 00 00 movl $0x0,0xa61c + 3337: 00 00 00 + printf(stdout, "bigarg test\n"); + 333a: e8 01 07 00 00 call 3a40 + exec("echo", args); + 333f: 58 pop %eax + 3340: 5a pop %edx + 3341: 68 a0 a5 00 00 push $0xa5a0 + 3346: 68 4d 3e 00 00 push $0x3e4d + 334b: e8 ab 05 00 00 call 38fb + printf(stdout, "bigarg test ok\n"); + 3350: 59 pop %ecx + 3351: 58 pop %eax + 3352: 68 8d 4c 00 00 push $0x4c8d + 3357: ff 35 58 5e 00 00 push 0x5e58 + 335d: e8 de 06 00 00 call 3a40 + fd = open("bigarg-ok", O_CREATE); + 3362: 58 pop %eax + 3363: 5a pop %edx + 3364: 68 00 02 00 00 push $0x200 + 3369: 68 76 4c 00 00 push $0x4c76 + 336e: e8 c8 05 00 00 call 393b + close(fd); + 3373: 89 04 24 mov %eax,(%esp) + 3376: e8 f0 05 00 00 call 396b + exit(); + 337b: e8 53 05 00 00 call 38d3 + printf(stdout, "bigarg test failed!\n"); + 3380: 50 push %eax + 3381: 50 push %eax + 3382: 68 b6 4c 00 00 push $0x4cb6 + 3387: ff 35 58 5e 00 00 push 0x5e58 + 338d: e8 ae 06 00 00 call 3a40 + exit(); + 3392: e8 3c 05 00 00 call 38d3 + printf(stdout, "bigargtest: fork failed\n"); + 3397: 52 push %edx + 3398: 52 push %edx + 3399: 68 9d 4c 00 00 push $0x4c9d + 339e: ff 35 58 5e 00 00 push 0x5e58 + 33a4: e8 97 06 00 00 call 3a40 + exit(); + 33a9: e8 25 05 00 00 call 38d3 + 33ae: 66 90 xchg %ax,%ax + +000033b0 : +void fsfull() { + 33b0: 55 push %ebp + 33b1: 89 e5 mov %esp,%ebp + 33b3: 57 push %edi + 33b4: 56 push %esi + for (nfiles = 0;; nfiles++) { + 33b5: 31 f6 xor %esi,%esi +void fsfull() { + 33b7: 53 push %ebx + 33b8: 83 ec 54 sub $0x54,%esp + printf(1, "fsfull test\n"); + 33bb: 68 cb 4c 00 00 push $0x4ccb + 33c0: 6a 01 push $0x1 + 33c2: e8 79 06 00 00 call 3a40 + 33c7: 83 c4 10 add $0x10,%esp + 33ca: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + name[1] = '0' + nfiles / 1000; + 33d0: b8 d3 4d 62 10 mov $0x10624dd3,%eax + name[3] = '0' + (nfiles % 100) / 10; + 33d5: b9 cd cc cc cc mov $0xcccccccd,%ecx + printf(1, "writing %s\n", name); + 33da: 83 ec 04 sub $0x4,%esp + name[0] = 'f'; + 33dd: c6 45 a8 66 movb $0x66,-0x58(%ebp) + name[1] = '0' + nfiles / 1000; + 33e1: f7 e6 mul %esi + name[5] = '\0'; + 33e3: c6 45 ad 00 movb $0x0,-0x53(%ebp) + name[1] = '0' + nfiles / 1000; + 33e7: c1 ea 06 shr $0x6,%edx + 33ea: 8d 42 30 lea 0x30(%edx),%eax + 33ed: 88 45 a9 mov %al,-0x57(%ebp) + name[2] = '0' + (nfiles % 1000) / 100; + 33f0: 69 c2 e8 03 00 00 imul $0x3e8,%edx,%eax + 33f6: 89 f2 mov %esi,%edx + 33f8: 29 c2 sub %eax,%edx + 33fa: b8 1f 85 eb 51 mov $0x51eb851f,%eax + 33ff: f7 e2 mul %edx + name[3] = '0' + (nfiles % 100) / 10; + 3401: b8 1f 85 eb 51 mov $0x51eb851f,%eax + name[2] = '0' + (nfiles % 1000) / 100; + 3406: c1 ea 05 shr $0x5,%edx + 3409: 83 c2 30 add $0x30,%edx + 340c: 88 55 aa mov %dl,-0x56(%ebp) + name[3] = '0' + (nfiles % 100) / 10; + 340f: f7 e6 mul %esi + 3411: c1 ea 05 shr $0x5,%edx + 3414: 6b c2 64 imul $0x64,%edx,%eax + 3417: 89 f2 mov %esi,%edx + 3419: 29 c2 sub %eax,%edx + 341b: 89 d0 mov %edx,%eax + 341d: f7 e1 mul %ecx + name[4] = '0' + (nfiles % 10); + 341f: 89 f0 mov %esi,%eax + name[3] = '0' + (nfiles % 100) / 10; + 3421: c1 ea 03 shr $0x3,%edx + 3424: 83 c2 30 add $0x30,%edx + 3427: 88 55 ab mov %dl,-0x55(%ebp) + name[4] = '0' + (nfiles % 10); + 342a: f7 e1 mul %ecx + 342c: 89 f0 mov %esi,%eax + 342e: c1 ea 03 shr $0x3,%edx + 3431: 8d 14 92 lea (%edx,%edx,4),%edx + 3434: 01 d2 add %edx,%edx + 3436: 29 d0 sub %edx,%eax + 3438: 83 c0 30 add $0x30,%eax + 343b: 88 45 ac mov %al,-0x54(%ebp) + printf(1, "writing %s\n", name); + 343e: 8d 45 a8 lea -0x58(%ebp),%eax + 3441: 50 push %eax + 3442: 68 d8 4c 00 00 push $0x4cd8 + 3447: 6a 01 push $0x1 + 3449: e8 f2 05 00 00 call 3a40 + int fd = open(name, O_CREATE | O_RDWR); + 344e: 58 pop %eax + 344f: 8d 45 a8 lea -0x58(%ebp),%eax + 3452: 5a pop %edx + 3453: 68 02 02 00 00 push $0x202 + 3458: 50 push %eax + 3459: e8 dd 04 00 00 call 393b + if (fd < 0) { + 345e: 83 c4 10 add $0x10,%esp + int fd = open(name, O_CREATE | O_RDWR); + 3461: 89 c7 mov %eax,%edi + if (fd < 0) { + 3463: 85 c0 test %eax,%eax + 3465: 78 4f js 34b6 + int total = 0; + 3467: 31 db xor %ebx,%ebx + 3469: eb 07 jmp 3472 + 346b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 346f: 90 nop + total += cc; + 3470: 01 c3 add %eax,%ebx + int cc = write(fd, buf, 512); + 3472: 83 ec 04 sub $0x4,%esp + 3475: 68 00 02 00 00 push $0x200 + 347a: 68 a0 85 00 00 push $0x85a0 + 347f: 57 push %edi + 3480: e8 be 04 00 00 call 3943 + if (cc < 512) { + 3485: 83 c4 10 add $0x10,%esp + 3488: 3d ff 01 00 00 cmp $0x1ff,%eax + 348d: 7f e1 jg 3470 + printf(1, "wrote %d bytes\n", total); + 348f: 83 ec 04 sub $0x4,%esp + 3492: 53 push %ebx + 3493: 68 f4 4c 00 00 push $0x4cf4 + 3498: 6a 01 push $0x1 + 349a: e8 a1 05 00 00 call 3a40 + close(fd); + 349f: 89 3c 24 mov %edi,(%esp) + 34a2: e8 c4 04 00 00 call 396b + if (total == 0) { + 34a7: 83 c4 10 add $0x10,%esp + 34aa: 85 db test %ebx,%ebx + 34ac: 74 1e je 34cc + for (nfiles = 0;; nfiles++) { + 34ae: 83 c6 01 add $0x1,%esi + 34b1: e9 1a ff ff ff jmp 33d0 + printf(1, "open %s failed\n", name); + 34b6: 83 ec 04 sub $0x4,%esp + 34b9: 8d 45 a8 lea -0x58(%ebp),%eax + 34bc: 50 push %eax + 34bd: 68 e4 4c 00 00 push $0x4ce4 + 34c2: 6a 01 push $0x1 + 34c4: e8 77 05 00 00 call 3a40 + break; + 34c9: 83 c4 10 add $0x10,%esp + name[1] = '0' + nfiles / 1000; + 34cc: bf d3 4d 62 10 mov $0x10624dd3,%edi + name[2] = '0' + (nfiles % 1000) / 100; + 34d1: bb 1f 85 eb 51 mov $0x51eb851f,%ebx + 34d6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 34dd: 8d 76 00 lea 0x0(%esi),%esi + name[1] = '0' + nfiles / 1000; + 34e0: 89 f0 mov %esi,%eax + unlink(name); + 34e2: 83 ec 0c sub $0xc,%esp + name[0] = 'f'; + 34e5: c6 45 a8 66 movb $0x66,-0x58(%ebp) + name[1] = '0' + nfiles / 1000; + 34e9: f7 e7 mul %edi + name[5] = '\0'; + 34eb: c6 45 ad 00 movb $0x0,-0x53(%ebp) + name[1] = '0' + nfiles / 1000; + 34ef: c1 ea 06 shr $0x6,%edx + 34f2: 8d 42 30 lea 0x30(%edx),%eax + 34f5: 88 45 a9 mov %al,-0x57(%ebp) + name[2] = '0' + (nfiles % 1000) / 100; + 34f8: 69 c2 e8 03 00 00 imul $0x3e8,%edx,%eax + 34fe: 89 f2 mov %esi,%edx + 3500: 29 c2 sub %eax,%edx + 3502: 89 d0 mov %edx,%eax + 3504: f7 e3 mul %ebx + name[3] = '0' + (nfiles % 100) / 10; + 3506: 89 f0 mov %esi,%eax + name[2] = '0' + (nfiles % 1000) / 100; + 3508: c1 ea 05 shr $0x5,%edx + 350b: 83 c2 30 add $0x30,%edx + 350e: 88 55 aa mov %dl,-0x56(%ebp) + name[3] = '0' + (nfiles % 100) / 10; + 3511: f7 e3 mul %ebx + 3513: c1 ea 05 shr $0x5,%edx + 3516: 6b ca 64 imul $0x64,%edx,%ecx + 3519: 89 f2 mov %esi,%edx + 351b: 29 ca sub %ecx,%edx + 351d: b9 cd cc cc cc mov $0xcccccccd,%ecx + 3522: 89 d0 mov %edx,%eax + 3524: f7 e1 mul %ecx + name[4] = '0' + (nfiles % 10); + 3526: 89 f0 mov %esi,%eax + name[3] = '0' + (nfiles % 100) / 10; + 3528: c1 ea 03 shr $0x3,%edx + 352b: 83 c2 30 add $0x30,%edx + 352e: 88 55 ab mov %dl,-0x55(%ebp) + name[4] = '0' + (nfiles % 10); + 3531: f7 e1 mul %ecx + 3533: 89 f0 mov %esi,%eax + nfiles--; + 3535: 83 ee 01 sub $0x1,%esi + name[4] = '0' + (nfiles % 10); + 3538: c1 ea 03 shr $0x3,%edx + 353b: 8d 14 92 lea (%edx,%edx,4),%edx + 353e: 01 d2 add %edx,%edx + 3540: 29 d0 sub %edx,%eax + 3542: 83 c0 30 add $0x30,%eax + 3545: 88 45 ac mov %al,-0x54(%ebp) + unlink(name); + 3548: 8d 45 a8 lea -0x58(%ebp),%eax + 354b: 50 push %eax + 354c: e8 02 04 00 00 call 3953 + while (nfiles >= 0) { + 3551: 83 c4 10 add $0x10,%esp + 3554: 83 fe ff cmp $0xffffffff,%esi + 3557: 75 87 jne 34e0 + printf(1, "fsfull test finished\n"); + 3559: 83 ec 08 sub $0x8,%esp + 355c: 68 04 4d 00 00 push $0x4d04 + 3561: 6a 01 push $0x1 + 3563: e8 d8 04 00 00 call 3a40 +} + 3568: 83 c4 10 add $0x10,%esp + 356b: 8d 65 f4 lea -0xc(%ebp),%esp + 356e: 5b pop %ebx + 356f: 5e pop %esi + 3570: 5f pop %edi + 3571: 5d pop %ebp + 3572: c3 ret + 3573: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 357a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + +00003580 : +void uio() { + 3580: 55 push %ebp + 3581: 89 e5 mov %esp,%ebp + 3583: 83 ec 10 sub $0x10,%esp + printf(1, "uio test\n"); + 3586: 68 1a 4d 00 00 push $0x4d1a + 358b: 6a 01 push $0x1 + 358d: e8 ae 04 00 00 call 3a40 + pid = fork(); + 3592: e8 34 03 00 00 call 38cb + if (pid == 0) { + 3597: 83 c4 10 add $0x10,%esp + 359a: 85 c0 test %eax,%eax + 359c: 74 1b je 35b9 + else if (pid < 0) { + 359e: 78 3d js 35dd + wait(); + 35a0: e8 36 03 00 00 call 38db + printf(1, "uio test done\n"); + 35a5: 83 ec 08 sub $0x8,%esp + 35a8: 68 24 4d 00 00 push $0x4d24 + 35ad: 6a 01 push $0x1 + 35af: e8 8c 04 00 00 call 3a40 +} + 35b4: 83 c4 10 add $0x10,%esp + 35b7: c9 leave + 35b8: c3 ret + asm volatile ("outb %0,%1" : : "a" (val), "d" (port)); + 35b9: b8 09 00 00 00 mov $0x9,%eax + 35be: ba 70 00 00 00 mov $0x70,%edx + 35c3: ee out %al,(%dx) + asm volatile ("inb %1,%0" : "=a" (val) : "d" (port)); + 35c4: ba 71 00 00 00 mov $0x71,%edx + 35c9: ec in (%dx),%al + printf(1, "uio: uio succeeded; test FAILED\n"); + 35ca: 52 push %edx + 35cb: 52 push %edx + 35cc: 68 b0 54 00 00 push $0x54b0 + 35d1: 6a 01 push $0x1 + 35d3: e8 68 04 00 00 call 3a40 + exit(); + 35d8: e8 f6 02 00 00 call 38d3 + printf(1, "fork failed\n"); + 35dd: 50 push %eax + 35de: 50 push %eax + 35df: 68 a9 4c 00 00 push $0x4ca9 + 35e4: 6a 01 push $0x1 + 35e6: e8 55 04 00 00 call 3a40 + exit(); + 35eb: e8 e3 02 00 00 call 38d3 + +000035f0 : +void argptest(){ + 35f0: 55 push %ebp + 35f1: 89 e5 mov %esp,%ebp + 35f3: 53 push %ebx + 35f4: 83 ec 0c sub $0xc,%esp + fd = open("init", O_RDONLY); + 35f7: 6a 00 push $0x0 + 35f9: 68 33 4d 00 00 push $0x4d33 + 35fe: e8 38 03 00 00 call 393b + if (fd < 0) { + 3603: 83 c4 10 add $0x10,%esp + 3606: 85 c0 test %eax,%eax + 3608: 78 39 js 3643 + read(fd, sbrk(0) - 1, -1); + 360a: 83 ec 0c sub $0xc,%esp + 360d: 89 c3 mov %eax,%ebx + 360f: 6a 00 push $0x0 + 3611: e8 0d 03 00 00 call 3923 + 3616: 83 c4 0c add $0xc,%esp + 3619: 83 e8 01 sub $0x1,%eax + 361c: 6a ff push $0xffffffff + 361e: 50 push %eax + 361f: 53 push %ebx + 3620: e8 c6 02 00 00 call 38eb + close(fd); + 3625: 89 1c 24 mov %ebx,(%esp) + 3628: e8 3e 03 00 00 call 396b + printf(1, "arg test passed\n"); + 362d: 58 pop %eax + 362e: 5a pop %edx + 362f: 68 45 4d 00 00 push $0x4d45 + 3634: 6a 01 push $0x1 + 3636: e8 05 04 00 00 call 3a40 +} + 363b: 8b 5d fc mov -0x4(%ebp),%ebx + 363e: 83 c4 10 add $0x10,%esp + 3641: c9 leave + 3642: c3 ret + printf(2, "open failed\n"); + 3643: 51 push %ecx + 3644: 51 push %ecx + 3645: 68 38 4d 00 00 push $0x4d38 + 364a: 6a 02 push $0x2 + 364c: e8 ef 03 00 00 call 3a40 + exit(); + 3651: e8 7d 02 00 00 call 38d3 + 3656: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 365d: 8d 76 00 lea 0x0(%esi),%esi + +00003660 : + randstate = randstate * 1664525 + 1013904223; + 3660: 69 05 54 5e 00 00 0d imul $0x19660d,0x5e54,%eax + 3667: 66 19 00 + 366a: 05 5f f3 6e 3c add $0x3c6ef35f,%eax + 366f: a3 54 5e 00 00 mov %eax,0x5e54 +} + 3674: c3 ret + 3675: 66 90 xchg %ax,%ax + 3677: 66 90 xchg %ax,%ax + 3679: 66 90 xchg %ax,%ax + 367b: 66 90 xchg %ax,%ax + 367d: 66 90 xchg %ax,%ax + 367f: 90 nop + +00003680 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 3680: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 3681: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 3683: 89 e5 mov %esp,%ebp + 3685: 53 push %ebx + 3686: 8b 4d 08 mov 0x8(%ebp),%ecx + 3689: 8b 5d 0c mov 0xc(%ebp),%ebx + 368c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 3690: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 3694: 88 14 01 mov %dl,(%ecx,%eax,1) + 3697: 83 c0 01 add $0x1,%eax + 369a: 84 d2 test %dl,%dl + 369c: 75 f2 jne 3690 + ; + } + return os; +} + 369e: 8b 5d fc mov -0x4(%ebp),%ebx + 36a1: 89 c8 mov %ecx,%eax + 36a3: c9 leave + 36a4: c3 ret + 36a5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 36ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000036b0 : + +int strcmp(const char *p, const char *q) { + 36b0: 55 push %ebp + 36b1: 89 e5 mov %esp,%ebp + 36b3: 53 push %ebx + 36b4: 8b 55 08 mov 0x8(%ebp),%edx + 36b7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 36ba: 0f b6 02 movzbl (%edx),%eax + 36bd: 84 c0 test %al,%al + 36bf: 75 17 jne 36d8 + 36c1: eb 3a jmp 36fd + 36c3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 36c7: 90 nop + 36c8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 36cc: 83 c2 01 add $0x1,%edx + 36cf: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 36d2: 84 c0 test %al,%al + 36d4: 74 1a je 36f0 + p++, q++; + 36d6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 36d8: 0f b6 19 movzbl (%ecx),%ebx + 36db: 38 c3 cmp %al,%bl + 36dd: 74 e9 je 36c8 + } + return (uchar) * p - (uchar) * q; + 36df: 29 d8 sub %ebx,%eax +} + 36e1: 8b 5d fc mov -0x4(%ebp),%ebx + 36e4: c9 leave + 36e5: c3 ret + 36e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 36ed: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 36f0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 36f4: 31 c0 xor %eax,%eax + 36f6: 29 d8 sub %ebx,%eax +} + 36f8: 8b 5d fc mov -0x4(%ebp),%ebx + 36fb: c9 leave + 36fc: c3 ret + return (uchar) * p - (uchar) * q; + 36fd: 0f b6 19 movzbl (%ecx),%ebx + 3700: 31 c0 xor %eax,%eax + 3702: eb db jmp 36df + 3704: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 370b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 370f: 90 nop + +00003710 : + +uint strlen(const char *s) { + 3710: 55 push %ebp + 3711: 89 e5 mov %esp,%ebp + 3713: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 3716: 80 3a 00 cmpb $0x0,(%edx) + 3719: 74 15 je 3730 + 371b: 31 c0 xor %eax,%eax + 371d: 8d 76 00 lea 0x0(%esi),%esi + 3720: 83 c0 01 add $0x1,%eax + 3723: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 3727: 89 c1 mov %eax,%ecx + 3729: 75 f5 jne 3720 + ; + } + return n; +} + 372b: 89 c8 mov %ecx,%eax + 372d: 5d pop %ebp + 372e: c3 ret + 372f: 90 nop + for (n = 0; s[n]; n++) { + 3730: 31 c9 xor %ecx,%ecx +} + 3732: 5d pop %ebp + 3733: 89 c8 mov %ecx,%eax + 3735: c3 ret + 3736: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 373d: 8d 76 00 lea 0x0(%esi),%esi + +00003740 : + +void* memset(void *dst, int c, uint n) { + 3740: 55 push %ebp + 3741: 89 e5 mov %esp,%ebp + 3743: 57 push %edi + 3744: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 3747: 8b 4d 10 mov 0x10(%ebp),%ecx + 374a: 8b 45 0c mov 0xc(%ebp),%eax + 374d: 89 d7 mov %edx,%edi + 374f: fc cld + 3750: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 3752: 8b 7d fc mov -0x4(%ebp),%edi + 3755: 89 d0 mov %edx,%eax + 3757: c9 leave + 3758: c3 ret + 3759: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00003760 : + +char* strchr(const char *s, char c) { + 3760: 55 push %ebp + 3761: 89 e5 mov %esp,%ebp + 3763: 8b 45 08 mov 0x8(%ebp),%eax + 3766: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 376a: 0f b6 10 movzbl (%eax),%edx + 376d: 84 d2 test %dl,%dl + 376f: 75 12 jne 3783 + 3771: eb 1d jmp 3790 + 3773: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 3777: 90 nop + 3778: 0f b6 50 01 movzbl 0x1(%eax),%edx + 377c: 83 c0 01 add $0x1,%eax + 377f: 84 d2 test %dl,%dl + 3781: 74 0d je 3790 + if (*s == c) { + 3783: 38 d1 cmp %dl,%cl + 3785: 75 f1 jne 3778 + return (char*)s; + } + } + return 0; +} + 3787: 5d pop %ebp + 3788: c3 ret + 3789: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 3790: 31 c0 xor %eax,%eax +} + 3792: 5d pop %ebp + 3793: c3 ret + 3794: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 379b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 379f: 90 nop + +000037a0 : + +char* gets(char *buf, int max) { + 37a0: 55 push %ebp + 37a1: 89 e5 mov %esp,%ebp + 37a3: 57 push %edi + 37a4: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 37a5: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 37a8: 53 push %ebx + for (i = 0; i + 1 < max;) { + 37a9: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 37ab: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 37ae: eb 27 jmp 37d7 + cc = read(0, &c, 1); + 37b0: 83 ec 04 sub $0x4,%esp + 37b3: 6a 01 push $0x1 + 37b5: 57 push %edi + 37b6: 6a 00 push $0x0 + 37b8: e8 2e 01 00 00 call 38eb + if (cc < 1) { + 37bd: 83 c4 10 add $0x10,%esp + 37c0: 85 c0 test %eax,%eax + 37c2: 7e 1d jle 37e1 + break; + } + buf[i++] = c; + 37c4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 37c8: 8b 55 08 mov 0x8(%ebp),%edx + 37cb: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 37cf: 3c 0a cmp $0xa,%al + 37d1: 74 1d je 37f0 + 37d3: 3c 0d cmp $0xd,%al + 37d5: 74 19 je 37f0 + for (i = 0; i + 1 < max;) { + 37d7: 89 de mov %ebx,%esi + 37d9: 83 c3 01 add $0x1,%ebx + 37dc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 37df: 7c cf jl 37b0 + break; + } + } + buf[i] = '\0'; + 37e1: 8b 45 08 mov 0x8(%ebp),%eax + 37e4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 37e8: 8d 65 f4 lea -0xc(%ebp),%esp + 37eb: 5b pop %ebx + 37ec: 5e pop %esi + 37ed: 5f pop %edi + 37ee: 5d pop %ebp + 37ef: c3 ret + buf[i] = '\0'; + 37f0: 8b 45 08 mov 0x8(%ebp),%eax + 37f3: 89 de mov %ebx,%esi + 37f5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 37f9: 8d 65 f4 lea -0xc(%ebp),%esp + 37fc: 5b pop %ebx + 37fd: 5e pop %esi + 37fe: 5f pop %edi + 37ff: 5d pop %ebp + 3800: c3 ret + 3801: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3808: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 380f: 90 nop + +00003810 : + +int stat(const char *n, struct stat *st) { + 3810: 55 push %ebp + 3811: 89 e5 mov %esp,%ebp + 3813: 56 push %esi + 3814: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 3815: 83 ec 08 sub $0x8,%esp + 3818: 6a 00 push $0x0 + 381a: ff 75 08 push 0x8(%ebp) + 381d: e8 19 01 00 00 call 393b + if (fd < 0) { + 3822: 83 c4 10 add $0x10,%esp + 3825: 85 c0 test %eax,%eax + 3827: 78 27 js 3850 + return -1; + } + r = fstat(fd, st); + 3829: 83 ec 08 sub $0x8,%esp + 382c: ff 75 0c push 0xc(%ebp) + 382f: 89 c3 mov %eax,%ebx + 3831: 50 push %eax + 3832: e8 cc 00 00 00 call 3903 + close(fd); + 3837: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 383a: 89 c6 mov %eax,%esi + close(fd); + 383c: e8 2a 01 00 00 call 396b + return r; + 3841: 83 c4 10 add $0x10,%esp +} + 3844: 8d 65 f8 lea -0x8(%ebp),%esp + 3847: 89 f0 mov %esi,%eax + 3849: 5b pop %ebx + 384a: 5e pop %esi + 384b: 5d pop %ebp + 384c: c3 ret + 384d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 3850: be ff ff ff ff mov $0xffffffff,%esi + 3855: eb ed jmp 3844 + 3857: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 385e: 66 90 xchg %ax,%ax + +00003860 : + +int atoi(const char *s) { + 3860: 55 push %ebp + 3861: 89 e5 mov %esp,%ebp + 3863: 53 push %ebx + 3864: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 3867: 0f be 02 movsbl (%edx),%eax + 386a: 8d 48 d0 lea -0x30(%eax),%ecx + 386d: 80 f9 09 cmp $0x9,%cl + n = 0; + 3870: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 3875: 77 1e ja 3895 + 3877: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 387e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 3880: 83 c2 01 add $0x1,%edx + 3883: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 3886: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 388a: 0f be 02 movsbl (%edx),%eax + 388d: 8d 58 d0 lea -0x30(%eax),%ebx + 3890: 80 fb 09 cmp $0x9,%bl + 3893: 76 eb jbe 3880 + } + return n; +} + 3895: 8b 5d fc mov -0x4(%ebp),%ebx + 3898: 89 c8 mov %ecx,%eax + 389a: c9 leave + 389b: c3 ret + 389c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000038a0 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 38a0: 55 push %ebp + 38a1: 89 e5 mov %esp,%ebp + 38a3: 57 push %edi + 38a4: 8b 45 10 mov 0x10(%ebp),%eax + 38a7: 8b 55 08 mov 0x8(%ebp),%edx + 38aa: 56 push %esi + 38ab: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 38ae: 85 c0 test %eax,%eax + 38b0: 7e 13 jle 38c5 + 38b2: 01 d0 add %edx,%eax + dst = vdst; + 38b4: 89 d7 mov %edx,%edi + 38b6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 38bd: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 38c0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 38c1: 39 f8 cmp %edi,%eax + 38c3: 75 fb jne 38c0 + } + return vdst; +} + 38c5: 5e pop %esi + 38c6: 89 d0 mov %edx,%eax + 38c8: 5f pop %edi + 38c9: 5d pop %ebp + 38ca: c3 ret + +000038cb : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 38cb: b8 01 00 00 00 mov $0x1,%eax + 38d0: cd 40 int $0x40 + 38d2: c3 ret + +000038d3 : +SYSCALL(exit) + 38d3: b8 02 00 00 00 mov $0x2,%eax + 38d8: cd 40 int $0x40 + 38da: c3 ret + +000038db : +SYSCALL(wait) + 38db: b8 03 00 00 00 mov $0x3,%eax + 38e0: cd 40 int $0x40 + 38e2: c3 ret + +000038e3 : +SYSCALL(pipe) + 38e3: b8 04 00 00 00 mov $0x4,%eax + 38e8: cd 40 int $0x40 + 38ea: c3 ret + +000038eb : +SYSCALL(read) + 38eb: b8 05 00 00 00 mov $0x5,%eax + 38f0: cd 40 int $0x40 + 38f2: c3 ret + +000038f3 : +SYSCALL(kill) + 38f3: b8 06 00 00 00 mov $0x6,%eax + 38f8: cd 40 int $0x40 + 38fa: c3 ret + +000038fb : +SYSCALL(exec) + 38fb: b8 07 00 00 00 mov $0x7,%eax + 3900: cd 40 int $0x40 + 3902: c3 ret + +00003903 : +SYSCALL(fstat) + 3903: b8 08 00 00 00 mov $0x8,%eax + 3908: cd 40 int $0x40 + 390a: c3 ret + +0000390b : +SYSCALL(chdir) + 390b: b8 09 00 00 00 mov $0x9,%eax + 3910: cd 40 int $0x40 + 3912: c3 ret + +00003913 : +SYSCALL(dup) + 3913: b8 0a 00 00 00 mov $0xa,%eax + 3918: cd 40 int $0x40 + 391a: c3 ret + +0000391b : +SYSCALL(getpid) + 391b: b8 0b 00 00 00 mov $0xb,%eax + 3920: cd 40 int $0x40 + 3922: c3 ret + +00003923 : +SYSCALL(sbrk) + 3923: b8 0c 00 00 00 mov $0xc,%eax + 3928: cd 40 int $0x40 + 392a: c3 ret + +0000392b : +SYSCALL(sleep) + 392b: b8 0d 00 00 00 mov $0xd,%eax + 3930: cd 40 int $0x40 + 3932: c3 ret + +00003933 : +SYSCALL(uptime) + 3933: b8 0e 00 00 00 mov $0xe,%eax + 3938: cd 40 int $0x40 + 393a: c3 ret + +0000393b : +SYSCALL(open) + 393b: b8 0f 00 00 00 mov $0xf,%eax + 3940: cd 40 int $0x40 + 3942: c3 ret + +00003943 : +SYSCALL(write) + 3943: b8 10 00 00 00 mov $0x10,%eax + 3948: cd 40 int $0x40 + 394a: c3 ret + +0000394b : +SYSCALL(mknod) + 394b: b8 11 00 00 00 mov $0x11,%eax + 3950: cd 40 int $0x40 + 3952: c3 ret + +00003953 : +SYSCALL(unlink) + 3953: b8 12 00 00 00 mov $0x12,%eax + 3958: cd 40 int $0x40 + 395a: c3 ret + +0000395b : +SYSCALL(link) + 395b: b8 13 00 00 00 mov $0x13,%eax + 3960: cd 40 int $0x40 + 3962: c3 ret + +00003963 : +SYSCALL(mkdir) + 3963: b8 14 00 00 00 mov $0x14,%eax + 3968: cd 40 int $0x40 + 396a: c3 ret + +0000396b : +SYSCALL(close) + 396b: b8 15 00 00 00 mov $0x15,%eax + 3970: cd 40 int $0x40 + 3972: c3 ret + +00003973 : +SYSCALL(getch) + 3973: b8 16 00 00 00 mov $0x16,%eax + 3978: cd 40 int $0x40 + 397a: c3 ret + +0000397b : +SYSCALL(greeting) + 397b: b8 17 00 00 00 mov $0x17,%eax + 3980: cd 40 int $0x40 + 3982: c3 ret + +00003983 : +SYSCALL(shutdown) + 3983: b8 18 00 00 00 mov $0x18,%eax + 3988: cd 40 int $0x40 + 398a: c3 ret + 398b: 66 90 xchg %ax,%ax + 398d: 66 90 xchg %ax,%ax + 398f: 90 nop + +00003990 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 3990: 55 push %ebp + 3991: 89 e5 mov %esp,%ebp + 3993: 57 push %edi + 3994: 56 push %esi + 3995: 53 push %ebx + 3996: 83 ec 3c sub $0x3c,%esp + 3999: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 399c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 399e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 39a1: 85 d2 test %edx,%edx + 39a3: 0f 89 7f 00 00 00 jns 3a28 + 39a9: f6 45 08 01 testb $0x1,0x8(%ebp) + 39ad: 74 79 je 3a28 + neg = 1; + 39af: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 39b6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 39b8: 31 db xor %ebx,%ebx + 39ba: 8d 75 d7 lea -0x29(%ebp),%esi + 39bd: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 39c0: 89 c8 mov %ecx,%eax + 39c2: 31 d2 xor %edx,%edx + 39c4: 89 cf mov %ecx,%edi + 39c6: f7 75 c4 divl -0x3c(%ebp) + 39c9: 0f b6 92 60 55 00 00 movzbl 0x5560(%edx),%edx + 39d0: 89 45 c0 mov %eax,-0x40(%ebp) + 39d3: 89 d8 mov %ebx,%eax + 39d5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 39d8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 39db: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 39de: 39 7d c4 cmp %edi,-0x3c(%ebp) + 39e1: 76 dd jbe 39c0 + if (neg) { + 39e3: 8b 4d bc mov -0x44(%ebp),%ecx + 39e6: 85 c9 test %ecx,%ecx + 39e8: 74 0c je 39f6 + buf[i++] = '-'; + 39ea: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 39ef: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 39f1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 39f6: 8b 7d b8 mov -0x48(%ebp),%edi + 39f9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 39fd: eb 07 jmp 3a06 + 39ff: 90 nop + putc(fd, buf[i]); + 3a00: 0f b6 13 movzbl (%ebx),%edx + 3a03: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 3a06: 83 ec 04 sub $0x4,%esp + 3a09: 88 55 d7 mov %dl,-0x29(%ebp) + 3a0c: 6a 01 push $0x1 + 3a0e: 56 push %esi + 3a0f: 57 push %edi + 3a10: e8 2e ff ff ff call 3943 + while (--i >= 0) { + 3a15: 83 c4 10 add $0x10,%esp + 3a18: 39 de cmp %ebx,%esi + 3a1a: 75 e4 jne 3a00 + } +} + 3a1c: 8d 65 f4 lea -0xc(%ebp),%esp + 3a1f: 5b pop %ebx + 3a20: 5e pop %esi + 3a21: 5f pop %edi + 3a22: 5d pop %ebp + 3a23: c3 ret + 3a24: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 3a28: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 3a2f: eb 87 jmp 39b8 + 3a31: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3a38: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3a3f: 90 nop + +00003a40 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 3a40: 55 push %ebp + 3a41: 89 e5 mov %esp,%ebp + 3a43: 57 push %edi + 3a44: 56 push %esi + 3a45: 53 push %ebx + 3a46: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 3a49: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 3a4c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 3a4f: 0f b6 13 movzbl (%ebx),%edx + 3a52: 84 d2 test %dl,%dl + 3a54: 74 6a je 3ac0 + ap = (uint*)(void*)&fmt + 1; + 3a56: 8d 45 10 lea 0x10(%ebp),%eax + 3a59: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 3a5c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 3a5f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 3a61: 89 45 d0 mov %eax,-0x30(%ebp) + 3a64: eb 36 jmp 3a9c + 3a66: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3a6d: 8d 76 00 lea 0x0(%esi),%esi + 3a70: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 3a73: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 3a78: 83 f8 25 cmp $0x25,%eax + 3a7b: 74 15 je 3a92 + write(fd, &c, 1); + 3a7d: 83 ec 04 sub $0x4,%esp + 3a80: 88 55 e7 mov %dl,-0x19(%ebp) + 3a83: 6a 01 push $0x1 + 3a85: 57 push %edi + 3a86: 56 push %esi + 3a87: e8 b7 fe ff ff call 3943 + 3a8c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 3a8f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 3a92: 0f b6 13 movzbl (%ebx),%edx + 3a95: 83 c3 01 add $0x1,%ebx + 3a98: 84 d2 test %dl,%dl + 3a9a: 74 24 je 3ac0 + c = fmt[i] & 0xff; + 3a9c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 3a9f: 85 c9 test %ecx,%ecx + 3aa1: 74 cd je 3a70 + } + } + else if (state == '%') { + 3aa3: 83 f9 25 cmp $0x25,%ecx + 3aa6: 75 ea jne 3a92 + if (c == 'd') { + 3aa8: 83 f8 25 cmp $0x25,%eax + 3aab: 0f 84 07 01 00 00 je 3bb8 + 3ab1: 83 e8 63 sub $0x63,%eax + 3ab4: 83 f8 15 cmp $0x15,%eax + 3ab7: 77 17 ja 3ad0 + 3ab9: ff 24 85 08 55 00 00 jmp *0x5508(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 3ac0: 8d 65 f4 lea -0xc(%ebp),%esp + 3ac3: 5b pop %ebx + 3ac4: 5e pop %esi + 3ac5: 5f pop %edi + 3ac6: 5d pop %ebp + 3ac7: c3 ret + 3ac8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3acf: 90 nop + write(fd, &c, 1); + 3ad0: 83 ec 04 sub $0x4,%esp + 3ad3: 88 55 d4 mov %dl,-0x2c(%ebp) + 3ad6: 6a 01 push $0x1 + 3ad8: 57 push %edi + 3ad9: 56 push %esi + 3ada: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 3ade: e8 60 fe ff ff call 3943 + putc(fd, c); + 3ae3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 3ae7: 83 c4 0c add $0xc,%esp + 3aea: 88 55 e7 mov %dl,-0x19(%ebp) + 3aed: 6a 01 push $0x1 + 3aef: 57 push %edi + 3af0: 56 push %esi + 3af1: e8 4d fe ff ff call 3943 + putc(fd, c); + 3af6: 83 c4 10 add $0x10,%esp + state = 0; + 3af9: 31 c9 xor %ecx,%ecx + 3afb: eb 95 jmp 3a92 + 3afd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 3b00: 83 ec 0c sub $0xc,%esp + 3b03: b9 10 00 00 00 mov $0x10,%ecx + 3b08: 6a 00 push $0x0 + 3b0a: 8b 45 d0 mov -0x30(%ebp),%eax + 3b0d: 8b 10 mov (%eax),%edx + 3b0f: 89 f0 mov %esi,%eax + 3b11: e8 7a fe ff ff call 3990 + ap++; + 3b16: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 3b1a: 83 c4 10 add $0x10,%esp + state = 0; + 3b1d: 31 c9 xor %ecx,%ecx + 3b1f: e9 6e ff ff ff jmp 3a92 + 3b24: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 3b28: 8b 45 d0 mov -0x30(%ebp),%eax + 3b2b: 8b 10 mov (%eax),%edx + ap++; + 3b2d: 83 c0 04 add $0x4,%eax + 3b30: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 3b33: 85 d2 test %edx,%edx + 3b35: 0f 84 8d 00 00 00 je 3bc8 + while (*s != 0) { + 3b3b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 3b3e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 3b40: 84 c0 test %al,%al + 3b42: 0f 84 4a ff ff ff je 3a92 + 3b48: 89 5d d4 mov %ebx,-0x2c(%ebp) + 3b4b: 89 d3 mov %edx,%ebx + 3b4d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 3b50: 83 ec 04 sub $0x4,%esp + s++; + 3b53: 83 c3 01 add $0x1,%ebx + 3b56: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 3b59: 6a 01 push $0x1 + 3b5b: 57 push %edi + 3b5c: 56 push %esi + 3b5d: e8 e1 fd ff ff call 3943 + while (*s != 0) { + 3b62: 0f b6 03 movzbl (%ebx),%eax + 3b65: 83 c4 10 add $0x10,%esp + 3b68: 84 c0 test %al,%al + 3b6a: 75 e4 jne 3b50 + state = 0; + 3b6c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 3b6f: 31 c9 xor %ecx,%ecx + 3b71: e9 1c ff ff ff jmp 3a92 + 3b76: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3b7d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 3b80: 83 ec 0c sub $0xc,%esp + 3b83: b9 0a 00 00 00 mov $0xa,%ecx + 3b88: 6a 01 push $0x1 + 3b8a: e9 7b ff ff ff jmp 3b0a + 3b8f: 90 nop + putc(fd, *ap); + 3b90: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 3b93: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 3b96: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 3b98: 6a 01 push $0x1 + 3b9a: 57 push %edi + 3b9b: 56 push %esi + putc(fd, *ap); + 3b9c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 3b9f: e8 9f fd ff ff call 3943 + ap++; + 3ba4: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 3ba8: 83 c4 10 add $0x10,%esp + state = 0; + 3bab: 31 c9 xor %ecx,%ecx + 3bad: e9 e0 fe ff ff jmp 3a92 + 3bb2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 3bb8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 3bbb: 83 ec 04 sub $0x4,%esp + 3bbe: e9 2a ff ff ff jmp 3aed + 3bc3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 3bc7: 90 nop + s = "(null)"; + 3bc8: ba fe 54 00 00 mov $0x54fe,%edx + while (*s != 0) { + 3bcd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 3bd0: b8 28 00 00 00 mov $0x28,%eax + 3bd5: 89 d3 mov %edx,%ebx + 3bd7: e9 74 ff ff ff jmp 3b50 + 3bdc: 66 90 xchg %ax,%ax + 3bde: 66 90 xchg %ax,%ax + +00003be0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 3be0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 3be1: a1 20 a6 00 00 mov 0xa620,%eax +void free(void *ap) { + 3be6: 89 e5 mov %esp,%ebp + 3be8: 57 push %edi + 3be9: 56 push %esi + 3bea: 53 push %ebx + 3beb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 3bee: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 3bf1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3bf8: 89 c2 mov %eax,%edx + 3bfa: 8b 00 mov (%eax),%eax + 3bfc: 39 ca cmp %ecx,%edx + 3bfe: 73 30 jae 3c30 + 3c00: 39 c1 cmp %eax,%ecx + 3c02: 72 04 jb 3c08 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 3c04: 39 c2 cmp %eax,%edx + 3c06: 72 f0 jb 3bf8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 3c08: 8b 73 fc mov -0x4(%ebx),%esi + 3c0b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 3c0e: 39 f8 cmp %edi,%eax + 3c10: 74 30 je 3c42 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 3c12: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 3c15: 8b 42 04 mov 0x4(%edx),%eax + 3c18: 8d 34 c2 lea (%edx,%eax,8),%esi + 3c1b: 39 f1 cmp %esi,%ecx + 3c1d: 74 3a je 3c59 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 3c1f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 3c21: 5b pop %ebx + freep = p; + 3c22: 89 15 20 a6 00 00 mov %edx,0xa620 +} + 3c28: 5e pop %esi + 3c29: 5f pop %edi + 3c2a: 5d pop %ebp + 3c2b: c3 ret + 3c2c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 3c30: 39 c2 cmp %eax,%edx + 3c32: 72 c4 jb 3bf8 + 3c34: 39 c1 cmp %eax,%ecx + 3c36: 73 c0 jae 3bf8 + if (bp + bp->s.size == p->s.ptr) { + 3c38: 8b 73 fc mov -0x4(%ebx),%esi + 3c3b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 3c3e: 39 f8 cmp %edi,%eax + 3c40: 75 d0 jne 3c12 + bp->s.size += p->s.ptr->s.size; + 3c42: 03 70 04 add 0x4(%eax),%esi + 3c45: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 3c48: 8b 02 mov (%edx),%eax + 3c4a: 8b 00 mov (%eax),%eax + 3c4c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 3c4f: 8b 42 04 mov 0x4(%edx),%eax + 3c52: 8d 34 c2 lea (%edx,%eax,8),%esi + 3c55: 39 f1 cmp %esi,%ecx + 3c57: 75 c6 jne 3c1f + p->s.size += bp->s.size; + 3c59: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 3c5c: 89 15 20 a6 00 00 mov %edx,0xa620 + p->s.size += bp->s.size; + 3c62: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 3c65: 8b 4b f8 mov -0x8(%ebx),%ecx + 3c68: 89 0a mov %ecx,(%edx) +} + 3c6a: 5b pop %ebx + 3c6b: 5e pop %esi + 3c6c: 5f pop %edi + 3c6d: 5d pop %ebp + 3c6e: c3 ret + 3c6f: 90 nop + +00003c70 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 3c70: 55 push %ebp + 3c71: 89 e5 mov %esp,%ebp + 3c73: 57 push %edi + 3c74: 56 push %esi + 3c75: 53 push %ebx + 3c76: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 3c79: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 3c7c: 8b 3d 20 a6 00 00 mov 0xa620,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 3c82: 8d 70 07 lea 0x7(%eax),%esi + 3c85: c1 ee 03 shr $0x3,%esi + 3c88: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 3c8b: 85 ff test %edi,%edi + 3c8d: 0f 84 9d 00 00 00 je 3d30 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 3c93: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 3c95: 8b 4a 04 mov 0x4(%edx),%ecx + 3c98: 39 f1 cmp %esi,%ecx + 3c9a: 73 6a jae 3d06 + 3c9c: bb 00 10 00 00 mov $0x1000,%ebx + 3ca1: 39 de cmp %ebx,%esi + 3ca3: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 3ca6: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 3cad: 89 45 e4 mov %eax,-0x1c(%ebp) + 3cb0: eb 17 jmp 3cc9 + 3cb2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 3cb8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 3cba: 8b 48 04 mov 0x4(%eax),%ecx + 3cbd: 39 f1 cmp %esi,%ecx + 3cbf: 73 4f jae 3d10 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 3cc1: 8b 3d 20 a6 00 00 mov 0xa620,%edi + 3cc7: 89 c2 mov %eax,%edx + 3cc9: 39 d7 cmp %edx,%edi + 3ccb: 75 eb jne 3cb8 + p = sbrk(nu * sizeof(Header)); + 3ccd: 83 ec 0c sub $0xc,%esp + 3cd0: ff 75 e4 push -0x1c(%ebp) + 3cd3: e8 4b fc ff ff call 3923 + if (p == (char*)-1) { + 3cd8: 83 c4 10 add $0x10,%esp + 3cdb: 83 f8 ff cmp $0xffffffff,%eax + 3cde: 74 1c je 3cfc + hp->s.size = nu; + 3ce0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 3ce3: 83 ec 0c sub $0xc,%esp + 3ce6: 83 c0 08 add $0x8,%eax + 3ce9: 50 push %eax + 3cea: e8 f1 fe ff ff call 3be0 + return freep; + 3cef: 8b 15 20 a6 00 00 mov 0xa620,%edx + if ((p = morecore(nunits)) == 0) { + 3cf5: 83 c4 10 add $0x10,%esp + 3cf8: 85 d2 test %edx,%edx + 3cfa: 75 bc jne 3cb8 + return 0; + } + } + } +} + 3cfc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 3cff: 31 c0 xor %eax,%eax +} + 3d01: 5b pop %ebx + 3d02: 5e pop %esi + 3d03: 5f pop %edi + 3d04: 5d pop %ebp + 3d05: c3 ret + if (p->s.size >= nunits) { + 3d06: 89 d0 mov %edx,%eax + 3d08: 89 fa mov %edi,%edx + 3d0a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 3d10: 39 ce cmp %ecx,%esi + 3d12: 74 4c je 3d60 + p->s.size -= nunits; + 3d14: 29 f1 sub %esi,%ecx + 3d16: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 3d19: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 3d1c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 3d1f: 89 15 20 a6 00 00 mov %edx,0xa620 +} + 3d25: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 3d28: 83 c0 08 add $0x8,%eax +} + 3d2b: 5b pop %ebx + 3d2c: 5e pop %esi + 3d2d: 5f pop %edi + 3d2e: 5d pop %ebp + 3d2f: c3 ret + base.s.ptr = freep = prevp = &base; + 3d30: c7 05 20 a6 00 00 24 movl $0xa624,0xa620 + 3d37: a6 00 00 + base.s.size = 0; + 3d3a: bf 24 a6 00 00 mov $0xa624,%edi + base.s.ptr = freep = prevp = &base; + 3d3f: c7 05 24 a6 00 00 24 movl $0xa624,0xa624 + 3d46: a6 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 3d49: 89 fa mov %edi,%edx + base.s.size = 0; + 3d4b: c7 05 28 a6 00 00 00 movl $0x0,0xa628 + 3d52: 00 00 00 + if (p->s.size >= nunits) { + 3d55: e9 42 ff ff ff jmp 3c9c + 3d5a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 3d60: 8b 08 mov (%eax),%ecx + 3d62: 89 0a mov %ecx,(%edx) + 3d64: eb b9 jmp 3d1f diff --git a/usertests.c b/usertests.c new file mode 100644 index 0000000..a8a8d92 --- /dev/null +++ b/usertests.c @@ -0,0 +1,1779 @@ +#include "param.h" +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fs.h" +#include "fcntl.h" +#include "syscall.h" +#include "traps.h" +#include "memlayout.h" + +char buf[8192]; +char name[3]; +char *echoargv[] = { "echo", "ALL", "TESTS", "PASSED", 0 }; +int stdout = 1; + +// does chdir() call iput(p->cwd) in a transaction? +void iputtest(void) { + printf(stdout, "iput test\n"); + + if (mkdir("iputdir") < 0) { + printf(stdout, "mkdir failed\n"); + exit(); + } + if (chdir("iputdir") < 0) { + printf(stdout, "chdir iputdir failed\n"); + exit(); + } + if (unlink("../iputdir") < 0) { + printf(stdout, "unlink ../iputdir failed\n"); + exit(); + } + if (chdir("/") < 0) { + printf(stdout, "chdir / failed\n"); + exit(); + } + printf(stdout, "iput test ok\n"); +} + +// does exit() call iput(p->cwd) in a transaction? +void exitiputtest(void) { + int pid; + + printf(stdout, "exitiput test\n"); + + pid = fork(); + if (pid < 0) { + printf(stdout, "fork failed\n"); + exit(); + } + if (pid == 0) { + if (mkdir("iputdir") < 0) { + printf(stdout, "mkdir failed\n"); + exit(); + } + if (chdir("iputdir") < 0) { + printf(stdout, "child chdir failed\n"); + exit(); + } + if (unlink("../iputdir") < 0) { + printf(stdout, "unlink ../iputdir failed\n"); + exit(); + } + exit(); + } + wait(); + printf(stdout, "exitiput test ok\n"); +} + +// does the error path in open() for attempt to write a +// directory call iput() in a transaction? +// needs a hacked kernel that pauses just after the namei() +// call in sys_open(): +// if((ip = namei(path)) == 0) +// return -1; +// { +// int i; +// for(i = 0; i < 10000; i++) +// yield(); +// } + +void openiputtest(void) { + int pid; + + printf(stdout, "openiput test\n"); + if (mkdir("oidir") < 0) { + printf(stdout, "mkdir oidir failed\n"); + exit(); + } + pid = fork(); + if (pid < 0) { + printf(stdout, "fork failed\n"); + exit(); + } + if (pid == 0) { + int fd = open("oidir", O_RDWR); + if (fd >= 0) { + printf(stdout, "open directory for write succeeded\n"); + exit(); + } + exit(); + } + sleep(1); + if (unlink("oidir") != 0) { + printf(stdout, "unlink failed\n"); + exit(); + } + wait(); + printf(stdout, "openiput test ok\n"); +} + +// simple file system tests + +void opentest(void) { + int fd; + + printf(stdout, "open test\n"); + fd = open("echo", 0); + if (fd < 0) { + printf(stdout, "open echo failed!\n"); + exit(); + } + close(fd); + fd = open("doesnotexist", 0); + if (fd >= 0) { + printf(stdout, "open doesnotexist succeeded!\n"); + exit(); + } + printf(stdout, "open test ok\n"); +} + +void writetest(void) { + int fd; + int i; + + printf(stdout, "small file test\n"); + fd = open("small", O_CREATE | O_RDWR); + if (fd >= 0) { + printf(stdout, "creat small succeeded; ok\n"); + } + else { + printf(stdout, "error: creat small failed!\n"); + exit(); + } + for (i = 0; i < 100; i++) { + if (write(fd, "aaaaaaaaaa", 10) != 10) { + printf(stdout, "error: write aa %d new file failed\n", i); + exit(); + } + if (write(fd, "bbbbbbbbbb", 10) != 10) { + printf(stdout, "error: write bb %d new file failed\n", i); + exit(); + } + } + printf(stdout, "writes ok\n"); + close(fd); + fd = open("small", O_RDONLY); + if (fd >= 0) { + printf(stdout, "open small succeeded ok\n"); + } + else { + printf(stdout, "error: open small failed!\n"); + exit(); + } + i = read(fd, buf, 2000); + if (i == 2000) { + printf(stdout, "read succeeded ok\n"); + } + else { + printf(stdout, "read failed\n"); + exit(); + } + close(fd); + + if (unlink("small") < 0) { + printf(stdout, "unlink small failed\n"); + exit(); + } + printf(stdout, "small file test ok\n"); +} + +void writetest1(void) { + int i, fd, n; + + printf(stdout, "big files test\n"); + + fd = open("big", O_CREATE | O_RDWR); + if (fd < 0) { + printf(stdout, "error: creat big failed!\n"); + exit(); + } + + for (i = 0; i < MAXFILE; i++) { + ((int*)buf)[0] = i; + if (write(fd, buf, 512) != 512) { + printf(stdout, "error: write big file failed\n", i); + exit(); + } + } + + close(fd); + + fd = open("big", O_RDONLY); + if (fd < 0) { + printf(stdout, "error: open big failed!\n"); + exit(); + } + + n = 0; + for (;;) { + i = read(fd, buf, 512); + if (i == 0) { + if (n == MAXFILE - 1) { + printf(stdout, "read only %d blocks from big", n); + exit(); + } + break; + } + else if (i != 512) { + printf(stdout, "read failed %d\n", i); + exit(); + } + if (((int*)buf)[0] != n) { + printf(stdout, "read content of block %d is %d\n", + n, ((int*)buf)[0]); + exit(); + } + n++; + } + close(fd); + if (unlink("big") < 0) { + printf(stdout, "unlink big failed\n"); + exit(); + } + printf(stdout, "big files ok\n"); +} + +void createtest(void) { + int i, fd; + + printf(stdout, "many creates, followed by unlink test\n"); + + name[0] = 'a'; + name[2] = '\0'; + for (i = 0; i < 52; i++) { + name[1] = '0' + i; + fd = open(name, O_CREATE | O_RDWR); + close(fd); + } + name[0] = 'a'; + name[2] = '\0'; + for (i = 0; i < 52; i++) { + name[1] = '0' + i; + unlink(name); + } + printf(stdout, "many creates, followed by unlink; ok\n"); +} + +void dirtest(void){ + printf(stdout, "mkdir test\n"); + + if (mkdir("dir0") < 0) { + printf(stdout, "mkdir failed\n"); + exit(); + } + + if (chdir("dir0") < 0) { + printf(stdout, "chdir dir0 failed\n"); + exit(); + } + + if (chdir("..") < 0) { + printf(stdout, "chdir .. failed\n"); + exit(); + } + + if (unlink("dir0") < 0) { + printf(stdout, "unlink dir0 failed\n"); + exit(); + } + printf(stdout, "mkdir test ok\n"); +} + +void exectest(void) { + printf(stdout, "exec test\n"); + if (exec("echo", echoargv) < 0) { + printf(stdout, "exec echo failed\n"); + exit(); + } +} + +// simple fork and pipe read/write + +void pipe1(void) { + int fds[2], pid; + int seq, i, n, cc, total; + + if (pipe(fds) != 0) { + printf(1, "pipe() failed\n"); + exit(); + } + pid = fork(); + seq = 0; + if (pid == 0) { + close(fds[0]); + for (n = 0; n < 5; n++) { + for (i = 0; i < 1033; i++) { + buf[i] = seq++; + } + if (write(fds[1], buf, 1033) != 1033) { + printf(1, "pipe1 oops 1\n"); + exit(); + } + } + exit(); + } + else if (pid > 0) { + close(fds[1]); + total = 0; + cc = 1; + while ((n = read(fds[0], buf, cc)) > 0) { + for (i = 0; i < n; i++) { + if ((buf[i] & 0xff) != (seq++ & 0xff)) { + printf(1, "pipe1 oops 2\n"); + return; + } + } + total += n; + cc = cc * 2; + if (cc > sizeof(buf)) { + cc = sizeof(buf); + } + } + if (total != 5 * 1033) { + printf(1, "pipe1 oops 3 total %d\n", total); + exit(); + } + close(fds[0]); + wait(); + } + else { + printf(1, "fork() failed\n"); + exit(); + } + printf(1, "pipe1 ok\n"); +} + +// meant to be run w/ at most two CPUs +void preempt(void) { + int pid1, pid2, pid3; + int pfds[2]; + + printf(1, "preempt: "); + pid1 = fork(); + if (pid1 == 0) { + for (;;) { + ; + } + } + + pid2 = fork(); + if (pid2 == 0) { + for (;;) { + ; + } + } + + pipe(pfds); + pid3 = fork(); + if (pid3 == 0) { + close(pfds[0]); + if (write(pfds[1], "x", 1) != 1) { + printf(1, "preempt write error"); + } + close(pfds[1]); + for (;;) { + ; + } + } + + close(pfds[1]); + if (read(pfds[0], buf, sizeof(buf)) != 1) { + printf(1, "preempt read error"); + return; + } + close(pfds[0]); + printf(1, "kill... "); + kill(pid1); + kill(pid2); + kill(pid3); + printf(1, "wait... "); + wait(); + wait(); + wait(); + printf(1, "preempt ok\n"); +} + +// try to find any races between exit and wait +void exitwait(void) { + int i, pid; + + for (i = 0; i < 100; i++) { + pid = fork(); + if (pid < 0) { + printf(1, "fork failed\n"); + return; + } + if (pid) { + if (wait() != pid) { + printf(1, "wait wrong pid\n"); + return; + } + } + else { + exit(); + } + } + printf(1, "exitwait ok\n"); +} + +void mem(void) { + void *m1, *m2; + int pid, ppid; + + printf(1, "mem test\n"); + ppid = getpid(); + if ((pid = fork()) == 0) { + m1 = 0; + while ((m2 = malloc(10001)) != 0) { + *(char**)m2 = m1; + m1 = m2; + } + while (m1) { + m2 = *(char**)m1; + free(m1); + m1 = m2; + } + m1 = malloc(1024 * 20); + if (m1 == 0) { + printf(1, "couldn't allocate mem?!!\n"); + kill(ppid); + exit(); + } + free(m1); + printf(1, "mem ok\n"); + exit(); + } + else { + wait(); + } +} + +// More file system tests + +// two processes write to the same file descriptor +// is the offset shared? does inode locking work? +void sharedfd(void) { + int fd, pid, i, n, nc, np; + char buf[10]; + + printf(1, "sharedfd test\n"); + + unlink("sharedfd"); + fd = open("sharedfd", O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "fstests: cannot open sharedfd for writing"); + return; + } + pid = fork(); + memset(buf, pid == 0 ? 'c' : 'p', sizeof(buf)); + for (i = 0; i < 1000; i++) { + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { + printf(1, "fstests: write sharedfd failed\n"); + break; + } + } + if (pid == 0) { + exit(); + } + else { + wait(); + } + close(fd); + fd = open("sharedfd", 0); + if (fd < 0) { + printf(1, "fstests: cannot open sharedfd for reading\n"); + return; + } + nc = np = 0; + while ((n = read(fd, buf, sizeof(buf))) > 0) { + for (i = 0; i < sizeof(buf); i++) { + if (buf[i] == 'c') { + nc++; + } + if (buf[i] == 'p') { + np++; + } + } + } + close(fd); + unlink("sharedfd"); + if (nc == 10000 && np == 10000) { + printf(1, "sharedfd ok\n"); + } + else { + printf(1, "sharedfd oops %d %d\n", nc, np); + exit(); + } +} + +// four processes write different files at the same +// time, to test block allocation. +void fourfiles(void) { + int fd, pid, i, j, n, total, pi; + char *names[] = { "f0", "f1", "f2", "f3" }; + char *fname; + + printf(1, "fourfiles test\n"); + + for (pi = 0; pi < 4; pi++) { + fname = names[pi]; + unlink(fname); + + pid = fork(); + if (pid < 0) { + printf(1, "fork failed\n"); + exit(); + } + + if (pid == 0) { + fd = open(fname, O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "create failed\n"); + exit(); + } + + memset(buf, '0' + pi, 512); + for (i = 0; i < 12; i++) { + if ((n = write(fd, buf, 500)) != 500) { + printf(1, "write failed %d\n", n); + exit(); + } + } + exit(); + } + } + + for (pi = 0; pi < 4; pi++) { + wait(); + } + + for (i = 0; i < 2; i++) { + fname = names[i]; + fd = open(fname, 0); + total = 0; + while ((n = read(fd, buf, sizeof(buf))) > 0) { + for (j = 0; j < n; j++) { + if (buf[j] != '0' + i) { + printf(1, "wrong char\n"); + exit(); + } + } + total += n; + } + close(fd); + if (total != 12 * 500) { + printf(1, "wrong length %d\n", total); + exit(); + } + unlink(fname); + } + + printf(1, "fourfiles ok\n"); +} + +// four processes create and delete different files in same directory +void createdelete(void) { + enum { N = 20 }; + int pid, i, fd, pi; + char name[32]; + + printf(1, "createdelete test\n"); + + for (pi = 0; pi < 4; pi++) { + pid = fork(); + if (pid < 0) { + printf(1, "fork failed\n"); + exit(); + } + + if (pid == 0) { + name[0] = 'p' + pi; + name[2] = '\0'; + for (i = 0; i < N; i++) { + name[1] = '0' + i; + fd = open(name, O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "create failed\n"); + exit(); + } + close(fd); + if (i > 0 && (i % 2) == 0) { + name[1] = '0' + (i / 2); + if (unlink(name) < 0) { + printf(1, "unlink failed\n"); + exit(); + } + } + } + exit(); + } + } + + for (pi = 0; pi < 4; pi++) { + wait(); + } + + name[0] = name[1] = name[2] = 0; + for (i = 0; i < N; i++) { + for (pi = 0; pi < 4; pi++) { + name[0] = 'p' + pi; + name[1] = '0' + i; + fd = open(name, 0); + if ((i == 0 || i >= N / 2) && fd < 0) { + printf(1, "oops createdelete %s didn't exist\n", name); + exit(); + } + else if ((i >= 1 && i < N / 2) && fd >= 0) { + printf(1, "oops createdelete %s did exist\n", name); + exit(); + } + if (fd >= 0) { + close(fd); + } + } + } + + for (i = 0; i < N; i++) { + for (pi = 0; pi < 4; pi++) { + name[0] = 'p' + i; + name[1] = '0' + i; + unlink(name); + } + } + + printf(1, "createdelete ok\n"); +} + +// can I unlink a file and still read it? +void unlinkread(void) { + int fd, fd1; + + printf(1, "unlinkread test\n"); + fd = open("unlinkread", O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "create unlinkread failed\n"); + exit(); + } + write(fd, "hello", 5); + close(fd); + + fd = open("unlinkread", O_RDWR); + if (fd < 0) { + printf(1, "open unlinkread failed\n"); + exit(); + } + if (unlink("unlinkread") != 0) { + printf(1, "unlink unlinkread failed\n"); + exit(); + } + + fd1 = open("unlinkread", O_CREATE | O_RDWR); + write(fd1, "yyy", 3); + close(fd1); + + if (read(fd, buf, sizeof(buf)) != 5) { + printf(1, "unlinkread read failed"); + exit(); + } + if (buf[0] != 'h') { + printf(1, "unlinkread wrong data\n"); + exit(); + } + if (write(fd, buf, 10) != 10) { + printf(1, "unlinkread write failed\n"); + exit(); + } + close(fd); + unlink("unlinkread"); + printf(1, "unlinkread ok\n"); +} + +void linktest(void) { + int fd; + + printf(1, "linktest\n"); + + unlink("lf1"); + unlink("lf2"); + + fd = open("lf1", O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "create lf1 failed\n"); + exit(); + } + if (write(fd, "hello", 5) != 5) { + printf(1, "write lf1 failed\n"); + exit(); + } + close(fd); + + if (link("lf1", "lf2") < 0) { + printf(1, "link lf1 lf2 failed\n"); + exit(); + } + unlink("lf1"); + + if (open("lf1", 0) >= 0) { + printf(1, "unlinked lf1 but it is still there!\n"); + exit(); + } + + fd = open("lf2", 0); + if (fd < 0) { + printf(1, "open lf2 failed\n"); + exit(); + } + if (read(fd, buf, sizeof(buf)) != 5) { + printf(1, "read lf2 failed\n"); + exit(); + } + close(fd); + + if (link("lf2", "lf2") >= 0) { + printf(1, "link lf2 lf2 succeeded! oops\n"); + exit(); + } + + unlink("lf2"); + if (link("lf2", "lf1") >= 0) { + printf(1, "link non-existant succeeded! oops\n"); + exit(); + } + + if (link(".", "lf1") >= 0) { + printf(1, "link . lf1 succeeded! oops\n"); + exit(); + } + + printf(1, "linktest ok\n"); +} + +// test concurrent create/link/unlink of the same file +void concreate(void) { + char file[3]; + int i, pid, n, fd; + char fa[40]; + struct { + ushort inum; + char name[14]; + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + for (i = 0; i < 40; i++) { + file[1] = '0' + i; + unlink(file); + pid = fork(); + if (pid && (i % 3) == 1) { + link("C0", file); + } + else if (pid == 0 && (i % 5) == 1) { + link("C0", file); + } + else { + fd = open(file, O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "concreate create %s failed\n", file); + exit(); + } + close(fd); + } + if (pid == 0) { + exit(); + } + else { + wait(); + } + } + + memset(fa, 0, sizeof(fa)); + fd = open(".", 0); + n = 0; + while (read(fd, &de, sizeof(de)) > 0) { + if (de.inum == 0) { + continue; + } + if (de.name[0] == 'C' && de.name[2] == '\0') { + i = de.name[1] - '0'; + if (i < 0 || i >= sizeof(fa)) { + printf(1, "concreate weird file %s\n", de.name); + exit(); + } + if (fa[i]) { + printf(1, "concreate duplicate file %s\n", de.name); + exit(); + } + fa[i] = 1; + n++; + } + } + close(fd); + + if (n != 40) { + printf(1, "concreate not enough files in directory listing\n"); + exit(); + } + + for (i = 0; i < 40; i++) { + file[1] = '0' + i; + pid = fork(); + if (pid < 0) { + printf(1, "fork failed\n"); + exit(); + } + if (((i % 3) == 0 && pid == 0) || + ((i % 3) == 1 && pid != 0)) { + close(open(file, 0)); + close(open(file, 0)); + close(open(file, 0)); + close(open(file, 0)); + } + else { + unlink(file); + unlink(file); + unlink(file); + unlink(file); + } + if (pid == 0) { + exit(); + } + else { + wait(); + } + } + + printf(1, "concreate ok\n"); +} + +// another concurrent link/unlink/create test, +// to look for deadlocks. +void linkunlink() { + int pid, i; + + printf(1, "linkunlink test\n"); + + unlink("x"); + pid = fork(); + if (pid < 0) { + printf(1, "fork failed\n"); + exit(); + } + + unsigned int x = (pid ? 1 : 97); + for (i = 0; i < 100; i++) { + x = x * 1103515245 + 12345; + if ((x % 3) == 0) { + close(open("x", O_RDWR | O_CREATE)); + } + else if ((x % 3) == 1) { + link("cat", "x"); + } + else { + unlink("x"); + } + } + + if (pid) { + wait(); + } + else { + exit(); + } + + printf(1, "linkunlink ok\n"); +} + +// directory that uses indirect blocks +void bigdir(void) { + int i, fd; + char name[10]; + + printf(1, "bigdir test\n"); + unlink("bd"); + + fd = open("bd", O_CREATE); + if (fd < 0) { + printf(1, "bigdir create failed\n"); + exit(); + } + close(fd); + + for (i = 0; i < 500; i++) { + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if (link("bd", name) != 0) { + printf(1, "bigdir link failed\n"); + exit(); + } + } + + unlink("bd"); + for (i = 0; i < 500; i++) { + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if (unlink(name) != 0) { + printf(1, "bigdir unlink failed"); + exit(); + } + } + + printf(1, "bigdir ok\n"); +} + +void subdir(void) { + int fd, cc; + + printf(1, "subdir test\n"); + + unlink("ff"); + if (mkdir("dd") != 0) { + printf(1, "subdir mkdir dd failed\n"); + exit(); + } + + fd = open("dd/ff", O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "create dd/ff failed\n"); + exit(); + } + write(fd, "ff", 2); + close(fd); + + if (unlink("dd") >= 0) { + printf(1, "unlink dd (non-empty dir) succeeded!\n"); + exit(); + } + + if (mkdir("/dd/dd") != 0) { + printf(1, "subdir mkdir dd/dd failed\n"); + exit(); + } + + fd = open("dd/dd/ff", O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "create dd/dd/ff failed\n"); + exit(); + } + write(fd, "FF", 2); + close(fd); + + fd = open("dd/dd/../ff", 0); + if (fd < 0) { + printf(1, "open dd/dd/../ff failed\n"); + exit(); + } + cc = read(fd, buf, sizeof(buf)); + if (cc != 2 || buf[0] != 'f') { + printf(1, "dd/dd/../ff wrong content\n"); + exit(); + } + close(fd); + + if (link("dd/dd/ff", "dd/dd/ffff") != 0) { + printf(1, "link dd/dd/ff dd/dd/ffff failed\n"); + exit(); + } + + if (unlink("dd/dd/ff") != 0) { + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if (open("dd/dd/ff", O_RDONLY) >= 0) { + printf(1, "open (unlinked) dd/dd/ff succeeded\n"); + exit(); + } + + if (chdir("dd") != 0) { + printf(1, "chdir dd failed\n"); + exit(); + } + if (chdir("dd/../../dd") != 0) { + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if (chdir("dd/../../../dd") != 0) { + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if (chdir("./..") != 0) { + printf(1, "chdir ./.. failed\n"); + exit(); + } + + fd = open("dd/dd/ffff", 0); + if (fd < 0) { + printf(1, "open dd/dd/ffff failed\n"); + exit(); + } + if (read(fd, buf, sizeof(buf)) != 2) { + printf(1, "read dd/dd/ffff wrong len\n"); + exit(); + } + close(fd); + + if (open("dd/dd/ff", O_RDONLY) >= 0) { + printf(1, "open (unlinked) dd/dd/ff succeeded!\n"); + exit(); + } + + if (open("dd/ff/ff", O_CREATE | O_RDWR) >= 0) { + printf(1, "create dd/ff/ff succeeded!\n"); + exit(); + } + if (open("dd/xx/ff", O_CREATE | O_RDWR) >= 0) { + printf(1, "create dd/xx/ff succeeded!\n"); + exit(); + } + if (open("dd", O_CREATE) >= 0) { + printf(1, "create dd succeeded!\n"); + exit(); + } + if (open("dd", O_RDWR) >= 0) { + printf(1, "open dd rdwr succeeded!\n"); + exit(); + } + if (open("dd", O_WRONLY) >= 0) { + printf(1, "open dd wronly succeeded!\n"); + exit(); + } + if (link("dd/ff/ff", "dd/dd/xx") == 0) { + printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n"); + exit(); + } + if (link("dd/xx/ff", "dd/dd/xx") == 0) { + printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n"); + exit(); + } + if (link("dd/ff", "dd/dd/ffff") == 0) { + printf(1, "link dd/ff dd/dd/ffff succeeded!\n"); + exit(); + } + if (mkdir("dd/ff/ff") == 0) { + printf(1, "mkdir dd/ff/ff succeeded!\n"); + exit(); + } + if (mkdir("dd/xx/ff") == 0) { + printf(1, "mkdir dd/xx/ff succeeded!\n"); + exit(); + } + if (mkdir("dd/dd/ffff") == 0) { + printf(1, "mkdir dd/dd/ffff succeeded!\n"); + exit(); + } + if (unlink("dd/xx/ff") == 0) { + printf(1, "unlink dd/xx/ff succeeded!\n"); + exit(); + } + if (unlink("dd/ff/ff") == 0) { + printf(1, "unlink dd/ff/ff succeeded!\n"); + exit(); + } + if (chdir("dd/ff") == 0) { + printf(1, "chdir dd/ff succeeded!\n"); + exit(); + } + if (chdir("dd/xx") == 0) { + printf(1, "chdir dd/xx succeeded!\n"); + exit(); + } + + if (unlink("dd/dd/ffff") != 0) { + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if (unlink("dd/ff") != 0) { + printf(1, "unlink dd/ff failed\n"); + exit(); + } + if (unlink("dd") == 0) { + printf(1, "unlink non-empty dd succeeded!\n"); + exit(); + } + if (unlink("dd/dd") < 0) { + printf(1, "unlink dd/dd failed\n"); + exit(); + } + if (unlink("dd") < 0) { + printf(1, "unlink dd failed\n"); + exit(); + } + + printf(1, "subdir ok\n"); +} + +// test writes that are larger than the log. +void bigwrite(void) { + int fd, sz; + + printf(1, "bigwrite test\n"); + + unlink("bigwrite"); + for (sz = 499; sz < 12 * 512; sz += 471) { + fd = open("bigwrite", O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "cannot create bigwrite\n"); + exit(); + } + int i; + for (i = 0; i < 2; i++) { + int cc = write(fd, buf, sz); + if (cc != sz) { + printf(1, "write(%d) ret %d\n", sz, cc); + exit(); + } + } + close(fd); + unlink("bigwrite"); + } + + printf(1, "bigwrite ok\n"); +} + +void bigfile(void) { + int fd, i, total, cc; + + printf(1, "bigfile test\n"); + + unlink("bigfile"); + fd = open("bigfile", O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "cannot create bigfile"); + exit(); + } + for (i = 0; i < 20; i++) { + memset(buf, i, 600); + if (write(fd, buf, 600) != 600) { + printf(1, "write bigfile failed\n"); + exit(); + } + } + close(fd); + + fd = open("bigfile", 0); + if (fd < 0) { + printf(1, "cannot open bigfile\n"); + exit(); + } + total = 0; + for (i = 0;; i++) { + cc = read(fd, buf, 300); + if (cc < 0) { + printf(1, "read bigfile failed\n"); + exit(); + } + if (cc == 0) { + break; + } + if (cc != 300) { + printf(1, "short read bigfile\n"); + exit(); + } + if (buf[0] != i / 2 || buf[299] != i / 2) { + printf(1, "read bigfile wrong data\n"); + exit(); + } + total += cc; + } + close(fd); + if (total != 20 * 600) { + printf(1, "read bigfile wrong total\n"); + exit(); + } + unlink("bigfile"); + + printf(1, "bigfile test ok\n"); +} + +void fourteen(void) { + int fd; + + // DIRSIZ is 14. + printf(1, "fourteen test\n"); + + if (mkdir("12345678901234") != 0) { + printf(1, "mkdir 12345678901234 failed\n"); + exit(); + } + if (mkdir("12345678901234/123456789012345") != 0) { + printf(1, "mkdir 12345678901234/123456789012345 failed\n"); + exit(); + } + fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); + if (fd < 0) { + printf(1, "create 123456789012345/123456789012345/123456789012345 failed\n"); + exit(); + } + close(fd); + fd = open("12345678901234/12345678901234/12345678901234", 0); + if (fd < 0) { + printf(1, "open 12345678901234/12345678901234/12345678901234 failed\n"); + exit(); + } + close(fd); + + if (mkdir("12345678901234/12345678901234") == 0) { + printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); + exit(); + } + if (mkdir("123456789012345/12345678901234") == 0) { + printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); + exit(); + } + + printf(1, "fourteen ok\n"); +} + +void rmdot(void) { + printf(1, "rmdot test\n"); + if (mkdir("dots") != 0) { + printf(1, "mkdir dots failed\n"); + exit(); + } + if (chdir("dots") != 0) { + printf(1, "chdir dots failed\n"); + exit(); + } + if (unlink(".") == 0) { + printf(1, "rm . worked!\n"); + exit(); + } + if (unlink("..") == 0) { + printf(1, "rm .. worked!\n"); + exit(); + } + if (chdir("/") != 0) { + printf(1, "chdir / failed\n"); + exit(); + } + if (unlink("dots/.") == 0) { + printf(1, "unlink dots/. worked!\n"); + exit(); + } + if (unlink("dots/..") == 0) { + printf(1, "unlink dots/.. worked!\n"); + exit(); + } + if (unlink("dots") != 0) { + printf(1, "unlink dots failed!\n"); + exit(); + } + printf(1, "rmdot ok\n"); +} + +void dirfile(void) { + int fd; + + printf(1, "dir vs file\n"); + + fd = open("dirfile", O_CREATE); + if (fd < 0) { + printf(1, "create dirfile failed\n"); + exit(); + } + close(fd); + if (chdir("dirfile") == 0) { + printf(1, "chdir dirfile succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", 0); + if (fd >= 0) { + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", O_CREATE); + if (fd >= 0) { + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + if (mkdir("dirfile/xx") == 0) { + printf(1, "mkdir dirfile/xx succeeded!\n"); + exit(); + } + if (unlink("dirfile/xx") == 0) { + printf(1, "unlink dirfile/xx succeeded!\n"); + exit(); + } + if (link("README", "dirfile/xx") == 0) { + printf(1, "link to dirfile/xx succeeded!\n"); + exit(); + } + if (unlink("dirfile") != 0) { + printf(1, "unlink dirfile failed!\n"); + exit(); + } + + fd = open(".", O_RDWR); + if (fd >= 0) { + printf(1, "open . for writing succeeded!\n"); + exit(); + } + fd = open(".", 0); + if (write(fd, "x", 1) > 0) { + printf(1, "write . succeeded!\n"); + exit(); + } + close(fd); + + printf(1, "dir vs file OK\n"); +} + +// test that iput() is called at the end of _namei() +void iref(void) { + int i, fd; + + printf(1, "empty file name\n"); + + // the 50 is NINODE + for (i = 0; i < 50 + 1; i++) { + if (mkdir("irefd") != 0) { + printf(1, "mkdir irefd failed\n"); + exit(); + } + if (chdir("irefd") != 0) { + printf(1, "chdir irefd failed\n"); + exit(); + } + + mkdir(""); + link("README", ""); + fd = open("", O_CREATE); + if (fd >= 0) { + close(fd); + } + fd = open("xx", O_CREATE); + if (fd >= 0) { + close(fd); + } + unlink("xx"); + } + + chdir("/"); + printf(1, "empty file name OK\n"); +} + +// test that fork fails gracefully +// the forktest binary also does this, but it runs out of proc entries first. +// inside the bigger usertests binary, we run out of memory first. +void forktest(void) { + int n, pid; + + printf(1, "fork test\n"); + + for (n = 0; n < 1000; n++) { + pid = fork(); + if (pid < 0) { + break; + } + if (pid == 0) { + exit(); + } + } + + if (n == 1000) { + printf(1, "fork claimed to work 1000 times!\n"); + exit(); + } + + for (; n > 0; n--) { + if (wait() < 0) { + printf(1, "wait stopped early\n"); + exit(); + } + } + + if (wait() != -1) { + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); +} + +void sbrktest(void) { + int fds[2], pid, pids[10], ppid; + char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch; + uint amt; + + printf(stdout, "sbrk test\n"); + oldbrk = sbrk(0); + + // can one sbrk() less than a page? + a = sbrk(0); + int i; + for (i = 0; i < 5000; i++) { + b = sbrk(1); + if (b != a) { + printf(stdout, "sbrk test failed %d %x %x\n", i, a, b); + exit(); + } + *b = 1; + a = b + 1; + } + pid = fork(); + if (pid < 0) { + printf(stdout, "sbrk test fork failed\n"); + exit(); + } + c = sbrk(1); + c = sbrk(1); + if (c != a + 1) { + printf(stdout, "sbrk test failed post-fork\n"); + exit(); + } + if (pid == 0) { + exit(); + } + wait(); + + // can one grow address space to something big? +#define BIG (100 * 1024 * 1024) + a = sbrk(0); + amt = (BIG) -(uint)a; + p = sbrk(amt); + if (p != a) { + printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); + exit(); + } + lastaddr = (char*) (BIG - 1); +#pragma GCC diagnostic ignored "-Wstringop-overflow" + *lastaddr = 99; + + // can one de-allocate? + a = sbrk(0); + c = sbrk(-4096); + if (c == (char*)0xffffffff) { + printf(stdout, "sbrk could not deallocate\n"); + exit(); + } + c = sbrk(0); + if (c != a - 4096) { + printf(stdout, "sbrk deallocation produced wrong address, a %x c %x\n", a, c); + exit(); + } + + // can one re-allocate that page? + a = sbrk(0); + c = sbrk(4096); + if (c != a || sbrk(0) != a + 4096) { + printf(stdout, "sbrk re-allocation failed, a %x c %x\n", a, c); + exit(); + } + if (*lastaddr == 99) { + // should be zero + printf(stdout, "sbrk de-allocation didn't really deallocate\n"); + exit(); + } + + a = sbrk(0); + c = sbrk(-(sbrk(0) - oldbrk)); + if (c != a) { + printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c); + exit(); + } + + // can we read the kernel's memory? + for (a = (char*)(KERNBASE); a < (char*) (KERNBASE + 2000000); a += 50000) { + ppid = getpid(); + pid = fork(); + if (pid < 0) { + printf(stdout, "fork failed\n"); + exit(); + } + if (pid == 0) { + printf(stdout, "oops could read %x = %x\n", a, *a); + kill(ppid); + exit(); + } + wait(); + } + + // if we run the system out of memory, does it clean up the last + // failed allocation? + if (pipe(fds) != 0) { + printf(1, "pipe() failed\n"); + exit(); + } + for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { + if ((pids[i] = fork()) == 0) { + // allocate a lot of memory + sbrk(BIG - (uint)sbrk(0)); + write(fds[1], "x", 1); + // sit around until killed + for (;;) { sleep(1000); + } + } + if (pids[i] != -1) { + read(fds[0], &scratch, 1); + } + } + // if those failed allocations freed up the pages they did allocate, + // we'll be able to allocate here + c = sbrk(4096); + for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { + if (pids[i] == -1) { + continue; + } + kill(pids[i]); + wait(); + } + if (c == (char*)0xffffffff) { + printf(stdout, "failed sbrk leaked memory\n"); + exit(); + } + + if (sbrk(0) > oldbrk) { + sbrk(-(sbrk(0) - oldbrk)); + } + + printf(stdout, "sbrk test OK\n"); +} + +void validateint(int *p) { + int res; + asm ("mov %%esp, %%ebx\n\t" + "mov %3, %%esp\n\t" + "int %2\n\t" + "mov %%ebx, %%esp" : + "=a" (res) : + "a" (SYS_sleep), "n" (T_SYSCALL), "c" (p) : + "ebx"); +} + +void validatetest(void) { + int hi, pid; + uint p; + + printf(stdout, "validate test\n"); + hi = 1100 * 1024; + + for (p = 0; p <= (uint)hi; p += 4096) { + if ((pid = fork()) == 0) { + // try to crash the kernel by passing in a badly placed integer + validateint((int*)p); + exit(); + } + sleep(0); + sleep(0); + kill(pid); + wait(); + + // try to crash the kernel by passing in a bad string pointer + if (link("nosuchfile", (char*)p) != -1) { + printf(stdout, "link should not succeed\n"); + exit(); + } + } + + printf(stdout, "validate ok\n"); +} + +// does unintialized data start out zero? +char uninit[10000]; +void bsstest(void) { + int i; + + printf(stdout, "bss test\n"); + for (i = 0; i < sizeof(uninit); i++) { + if (uninit[i] != '\0') { + printf(stdout, "bss test failed\n"); + exit(); + } + } + printf(stdout, "bss test ok\n"); +} + +// does exec return an error if the arguments +// are larger than a page? or does it write +// below the stack and wreck the instructions/data? +void bigargtest(void) { + int pid, fd; + + unlink("bigarg-ok"); + pid = fork(); + if (pid == 0) { + static char *args[MAXARG]; + int i; + for (i = 0; i < MAXARG - 1; i++) { + args[i] = "bigargs test: failed\n "; + } + args[MAXARG - 1] = 0; + printf(stdout, "bigarg test\n"); + exec("echo", args); + printf(stdout, "bigarg test ok\n"); + fd = open("bigarg-ok", O_CREATE); + close(fd); + exit(); + } + else if (pid < 0) { + printf(stdout, "bigargtest: fork failed\n"); + exit(); + } + wait(); + fd = open("bigarg-ok", 0); + if (fd < 0) { + printf(stdout, "bigarg test failed!\n"); + exit(); + } + close(fd); + unlink("bigarg-ok"); +} + +// what happens when the file system runs out of blocks? +// answer: balloc panics, so this test is not useful. +void fsfull() { + int nfiles; + int fsblocks = 0; + + printf(1, "fsfull test\n"); + + for (nfiles = 0;; nfiles++) { + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + printf(1, "writing %s\n", name); + int fd = open(name, O_CREATE | O_RDWR); + if (fd < 0) { + printf(1, "open %s failed\n", name); + break; + } + int total = 0; + while (1) { + int cc = write(fd, buf, 512); + if (cc < 512) { + break; + } + total += cc; + fsblocks++; + } + printf(1, "wrote %d bytes\n", total); + close(fd); + if (total == 0) { + break; + } + } + + while (nfiles >= 0) { + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + unlink(name); + nfiles--; + } + + printf(1, "fsfull test finished\n"); +} + +void uio() { + #define RTC_ADDR 0x70 + #define RTC_DATA 0x71 + + ushort port = 0; + uchar val = 0; + int pid; + + printf(1, "uio test\n"); + pid = fork(); + if (pid == 0) { + port = RTC_ADDR; + val = 0x09; /* year */ + /* http://wiki.osdev.org/Inline_Assembly/Examples */ + asm volatile ("outb %0,%1" : : "a" (val), "d" (port)); + port = RTC_DATA; + asm volatile ("inb %1,%0" : "=a" (val) : "d" (port)); + printf(1, "uio: uio succeeded; test FAILED\n"); + exit(); + } + else if (pid < 0) { + printf(1, "fork failed\n"); + exit(); + } + wait(); + printf(1, "uio test done\n"); +} + +void argptest(){ + int fd; + fd = open("init", O_RDONLY); + if (fd < 0) { + printf(2, "open failed\n"); + exit(); + } + read(fd, sbrk(0) - 1, -1); + close(fd); + printf(1, "arg test passed\n"); +} + +unsigned long randstate = 1; +unsigned int rand() { + randstate = randstate * 1664525 + 1013904223; + return randstate; +} + +int main(int argc, char *argv[]) { + printf(1, "usertests starting\n"); + + if (open("usertests.ran", 0) >= 0) { + printf(1, "already ran user tests -- rebuild fs.img\n"); + exit(); + } + close(open("usertests.ran", O_CREATE)); + + argptest(); + createdelete(); + linkunlink(); + concreate(); + fourfiles(); + sharedfd(); + + bigargtest(); + bigwrite(); + bigargtest(); + bsstest(); + sbrktest(); + validatetest(); + + opentest(); + writetest(); + writetest1(); + createtest(); + + openiputtest(); + exitiputtest(); + iputtest(); + + mem(); + pipe1(); + preempt(); + exitwait(); + + rmdot(); + fourteen(); + bigfile(); + subdir(); + linktest(); + unlinkread(); + dirfile(); + iref(); + forktest(); + bigdir(); // slow + + uio(); + + exectest(); + + exit(); +} diff --git a/usertests.d b/usertests.d new file mode 100644 index 0000000..a4933d3 --- /dev/null +++ b/usertests.d @@ -0,0 +1,2 @@ +usertests.o: usertests.c /usr/include/stdc-predef.h param.h types.h \ + stat.h user.h fs.h fcntl.h syscall.h traps.h memlayout.h diff --git a/usertests.o b/usertests.o new file mode 100644 index 0000000..0abd717 Binary files /dev/null and b/usertests.o differ diff --git a/usertests.sym b/usertests.sym new file mode 100644 index 0000000..ebee436 --- /dev/null +++ b/usertests.sym @@ -0,0 +1,93 @@ +00000000 usertests.c +0000a5a0 args.0 +00000000 ulib.c +00000000 printf.c +00003990 printint +00005560 digits.0 +00000000 umalloc.c +0000a620 freep +0000a624 base +00003680 strcpy +00000d10 exitwait +00003a40 printf +00005e58 stdout +000032b0 bigargtest +0000397b greeting +000038a0 memmove +00000300 openiputtest +0000394b mknod +000037a0 gets +0000391b getpid +00000a20 pipe1 +00002b70 iref +00003c70 malloc +0000392b sleep +00000200 exitiputtest +000033b0 fsfull +00001bf0 bigdir +00002c90 forktest +00000670 writetest1 +00002400 bigwrite +00000e60 sharedfd +00005e54 randstate +000038e3 pipe +00005e80 uninit +00003973 getch +00002970 dirfile +00003943 write +00003240 bsstest +00005e5c echoargv +00003903 fstat +000038f3 kill +00003190 validatetest +000027f0 rmdot +0000390b chdir +000009d0 exectest +000038fb exec +000038db wait +00003660 rand +000038eb read +00000bb0 preempt +00003953 unlink +000035f0 argptest +00000d90 mem +000038cb fork +00003923 sbrk +00003933 uptime +00005e70 __bss_start +00003740 memset +00000840 createtest +00000000 main +00001220 createdelete +000036b0 strcmp +00003983 shutdown +00000490 writetest +00003913 dup +00002d40 sbrktest +00000400 opentest +00001d20 subdir +00003580 uio +000015d0 linktest +000085a0 buf +000008f0 dirtest +00000120 iputtest +00003810 stat +000024e0 bigfile +00005e70 _edata +0000a62c _end +00001440 unlinkread +0000395b link +000038d3 exit +00003860 atoi +00001ae0 linkunlink +00008590 name +00003710 strlen +0000393b open +00003760 strchr +000017e0 concreate +000026b0 fourteen +00003180 validateint +00001020 fourfiles +00003963 mkdir +0000396b close +00003be0 free diff --git a/usys.S b/usys.S new file mode 100644 index 0000000..e55cbb2 --- /dev/null +++ b/usys.S @@ -0,0 +1,37 @@ +# Generated by gensyscalls.pl. Do not edit. +# To change syscall numbers or add new syscalls, edit gensyscalls.pl + +#include "syscall.h" +#include "traps.h" + +#define SYSCALL(name) \ +.globl name; \ +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) +SYSCALL(exit) +SYSCALL(wait) +SYSCALL(pipe) +SYSCALL(read) +SYSCALL(kill) +SYSCALL(exec) +SYSCALL(fstat) +SYSCALL(chdir) +SYSCALL(dup) +SYSCALL(getpid) +SYSCALL(sbrk) +SYSCALL(sleep) +SYSCALL(uptime) +SYSCALL(open) +SYSCALL(write) +SYSCALL(mknod) +SYSCALL(unlink) +SYSCALL(link) +SYSCALL(mkdir) +SYSCALL(close) +SYSCALL(getch) +SYSCALL(greeting) +SYSCALL(shutdown) diff --git a/usys.o b/usys.o new file mode 100644 index 0000000..646f84f Binary files /dev/null and b/usys.o differ diff --git a/vectors.S b/vectors.S new file mode 100644 index 0000000..9e4041a --- /dev/null +++ b/vectors.S @@ -0,0 +1,1537 @@ +# generated by vectors.pl - do not edit +# handlers +.globl alltraps +.globl vector0 +vector0: + pushl $0 + pushl $0 + jmp alltraps +.globl vector1 +vector1: + pushl $0 + pushl $1 + jmp alltraps +.globl vector2 +vector2: + pushl $0 + pushl $2 + jmp alltraps +.globl vector3 +vector3: + pushl $0 + pushl $3 + jmp alltraps +.globl vector4 +vector4: + pushl $0 + pushl $4 + jmp alltraps +.globl vector5 +vector5: + pushl $0 + pushl $5 + jmp alltraps +.globl vector6 +vector6: + pushl $0 + pushl $6 + jmp alltraps +.globl vector7 +vector7: + pushl $0 + pushl $7 + jmp alltraps +.globl vector8 +vector8: + pushl $8 + jmp alltraps +.globl vector9 +vector9: + pushl $0 + pushl $9 + jmp alltraps +.globl vector10 +vector10: + pushl $10 + jmp alltraps +.globl vector11 +vector11: + pushl $11 + jmp alltraps +.globl vector12 +vector12: + pushl $12 + jmp alltraps +.globl vector13 +vector13: + pushl $13 + jmp alltraps +.globl vector14 +vector14: + pushl $14 + jmp alltraps +.globl vector15 +vector15: + pushl $0 + pushl $15 + jmp alltraps +.globl vector16 +vector16: + pushl $0 + pushl $16 + jmp alltraps +.globl vector17 +vector17: + pushl $17 + jmp alltraps +.globl vector18 +vector18: + pushl $0 + pushl $18 + jmp alltraps +.globl vector19 +vector19: + pushl $0 + pushl $19 + jmp alltraps +.globl vector20 +vector20: + pushl $0 + pushl $20 + jmp alltraps +.globl vector21 +vector21: + pushl $0 + pushl $21 + jmp alltraps +.globl vector22 +vector22: + pushl $0 + pushl $22 + jmp alltraps +.globl vector23 +vector23: + pushl $0 + pushl $23 + jmp alltraps +.globl vector24 +vector24: + pushl $0 + pushl $24 + jmp alltraps +.globl vector25 +vector25: + pushl $0 + pushl $25 + jmp alltraps +.globl vector26 +vector26: + pushl $0 + pushl $26 + jmp alltraps +.globl vector27 +vector27: + pushl $0 + pushl $27 + jmp alltraps +.globl vector28 +vector28: + pushl $0 + pushl $28 + jmp alltraps +.globl vector29 +vector29: + pushl $0 + pushl $29 + jmp alltraps +.globl vector30 +vector30: + pushl $0 + pushl $30 + jmp alltraps +.globl vector31 +vector31: + pushl $0 + pushl $31 + jmp alltraps +.globl vector32 +vector32: + pushl $0 + pushl $32 + jmp alltraps +.globl vector33 +vector33: + pushl $0 + pushl $33 + jmp alltraps +.globl vector34 +vector34: + pushl $0 + pushl $34 + jmp alltraps +.globl vector35 +vector35: + pushl $0 + pushl $35 + jmp alltraps +.globl vector36 +vector36: + pushl $0 + pushl $36 + jmp alltraps +.globl vector37 +vector37: + pushl $0 + pushl $37 + jmp alltraps +.globl vector38 +vector38: + pushl $0 + pushl $38 + jmp alltraps +.globl vector39 +vector39: + pushl $0 + pushl $39 + jmp alltraps +.globl vector40 +vector40: + pushl $0 + pushl $40 + jmp alltraps +.globl vector41 +vector41: + pushl $0 + pushl $41 + jmp alltraps +.globl vector42 +vector42: + pushl $0 + pushl $42 + jmp alltraps +.globl vector43 +vector43: + pushl $0 + pushl $43 + jmp alltraps +.globl vector44 +vector44: + pushl $0 + pushl $44 + jmp alltraps +.globl vector45 +vector45: + pushl $0 + pushl $45 + jmp alltraps +.globl vector46 +vector46: + pushl $0 + pushl $46 + jmp alltraps +.globl vector47 +vector47: + pushl $0 + pushl $47 + jmp alltraps +.globl vector48 +vector48: + pushl $0 + pushl $48 + jmp alltraps +.globl vector49 +vector49: + pushl $0 + pushl $49 + jmp alltraps +.globl vector50 +vector50: + pushl $0 + pushl $50 + jmp alltraps +.globl vector51 +vector51: + pushl $0 + pushl $51 + jmp alltraps +.globl vector52 +vector52: + pushl $0 + pushl $52 + jmp alltraps +.globl vector53 +vector53: + pushl $0 + pushl $53 + jmp alltraps +.globl vector54 +vector54: + pushl $0 + pushl $54 + jmp alltraps +.globl vector55 +vector55: + pushl $0 + pushl $55 + jmp alltraps +.globl vector56 +vector56: + pushl $0 + pushl $56 + jmp alltraps +.globl vector57 +vector57: + pushl $0 + pushl $57 + jmp alltraps +.globl vector58 +vector58: + pushl $0 + pushl $58 + jmp alltraps +.globl vector59 +vector59: + pushl $0 + pushl $59 + jmp alltraps +.globl vector60 +vector60: + pushl $0 + pushl $60 + jmp alltraps +.globl vector61 +vector61: + pushl $0 + pushl $61 + jmp alltraps +.globl vector62 +vector62: + pushl $0 + pushl $62 + jmp alltraps +.globl vector63 +vector63: + pushl $0 + pushl $63 + jmp alltraps +.globl vector64 +vector64: + pushl $0 + pushl $64 + jmp alltraps +.globl vector65 +vector65: + pushl $0 + pushl $65 + jmp alltraps +.globl vector66 +vector66: + pushl $0 + pushl $66 + jmp alltraps +.globl vector67 +vector67: + pushl $0 + pushl $67 + jmp alltraps +.globl vector68 +vector68: + pushl $0 + pushl $68 + jmp alltraps +.globl vector69 +vector69: + pushl $0 + pushl $69 + jmp alltraps +.globl vector70 +vector70: + pushl $0 + pushl $70 + jmp alltraps +.globl vector71 +vector71: + pushl $0 + pushl $71 + jmp alltraps +.globl vector72 +vector72: + pushl $0 + pushl $72 + jmp alltraps +.globl vector73 +vector73: + pushl $0 + pushl $73 + jmp alltraps +.globl vector74 +vector74: + pushl $0 + pushl $74 + jmp alltraps +.globl vector75 +vector75: + pushl $0 + pushl $75 + jmp alltraps +.globl vector76 +vector76: + pushl $0 + pushl $76 + jmp alltraps +.globl vector77 +vector77: + pushl $0 + pushl $77 + jmp alltraps +.globl vector78 +vector78: + pushl $0 + pushl $78 + jmp alltraps +.globl vector79 +vector79: + pushl $0 + pushl $79 + jmp alltraps +.globl vector80 +vector80: + pushl $0 + pushl $80 + jmp alltraps +.globl vector81 +vector81: + pushl $0 + pushl $81 + jmp alltraps +.globl vector82 +vector82: + pushl $0 + pushl $82 + jmp alltraps +.globl vector83 +vector83: + pushl $0 + pushl $83 + jmp alltraps +.globl vector84 +vector84: + pushl $0 + pushl $84 + jmp alltraps +.globl vector85 +vector85: + pushl $0 + pushl $85 + jmp alltraps +.globl vector86 +vector86: + pushl $0 + pushl $86 + jmp alltraps +.globl vector87 +vector87: + pushl $0 + pushl $87 + jmp alltraps +.globl vector88 +vector88: + pushl $0 + pushl $88 + jmp alltraps +.globl vector89 +vector89: + pushl $0 + pushl $89 + jmp alltraps +.globl vector90 +vector90: + pushl $0 + pushl $90 + jmp alltraps +.globl vector91 +vector91: + pushl $0 + pushl $91 + jmp alltraps +.globl vector92 +vector92: + pushl $0 + pushl $92 + jmp alltraps +.globl vector93 +vector93: + pushl $0 + pushl $93 + jmp alltraps +.globl vector94 +vector94: + pushl $0 + pushl $94 + jmp alltraps +.globl vector95 +vector95: + pushl $0 + pushl $95 + jmp alltraps +.globl vector96 +vector96: + pushl $0 + pushl $96 + jmp alltraps +.globl vector97 +vector97: + pushl $0 + pushl $97 + jmp alltraps +.globl vector98 +vector98: + pushl $0 + pushl $98 + jmp alltraps +.globl vector99 +vector99: + pushl $0 + pushl $99 + jmp alltraps +.globl vector100 +vector100: + pushl $0 + pushl $100 + jmp alltraps +.globl vector101 +vector101: + pushl $0 + pushl $101 + jmp alltraps +.globl vector102 +vector102: + pushl $0 + pushl $102 + jmp alltraps +.globl vector103 +vector103: + pushl $0 + pushl $103 + jmp alltraps +.globl vector104 +vector104: + pushl $0 + pushl $104 + jmp alltraps +.globl vector105 +vector105: + pushl $0 + pushl $105 + jmp alltraps +.globl vector106 +vector106: + pushl $0 + pushl $106 + jmp alltraps +.globl vector107 +vector107: + pushl $0 + pushl $107 + jmp alltraps +.globl vector108 +vector108: + pushl $0 + pushl $108 + jmp alltraps +.globl vector109 +vector109: + pushl $0 + pushl $109 + jmp alltraps +.globl vector110 +vector110: + pushl $0 + pushl $110 + jmp alltraps +.globl vector111 +vector111: + pushl $0 + pushl $111 + jmp alltraps +.globl vector112 +vector112: + pushl $0 + pushl $112 + jmp alltraps +.globl vector113 +vector113: + pushl $0 + pushl $113 + jmp alltraps +.globl vector114 +vector114: + pushl $0 + pushl $114 + jmp alltraps +.globl vector115 +vector115: + pushl $0 + pushl $115 + jmp alltraps +.globl vector116 +vector116: + pushl $0 + pushl $116 + jmp alltraps +.globl vector117 +vector117: + pushl $0 + pushl $117 + jmp alltraps +.globl vector118 +vector118: + pushl $0 + pushl $118 + jmp alltraps +.globl vector119 +vector119: + pushl $0 + pushl $119 + jmp alltraps +.globl vector120 +vector120: + pushl $0 + pushl $120 + jmp alltraps +.globl vector121 +vector121: + pushl $0 + pushl $121 + jmp alltraps +.globl vector122 +vector122: + pushl $0 + pushl $122 + jmp alltraps +.globl vector123 +vector123: + pushl $0 + pushl $123 + jmp alltraps +.globl vector124 +vector124: + pushl $0 + pushl $124 + jmp alltraps +.globl vector125 +vector125: + pushl $0 + pushl $125 + jmp alltraps +.globl vector126 +vector126: + pushl $0 + pushl $126 + jmp alltraps +.globl vector127 +vector127: + pushl $0 + pushl $127 + jmp alltraps +.globl vector128 +vector128: + pushl $0 + pushl $128 + jmp alltraps +.globl vector129 +vector129: + pushl $0 + pushl $129 + jmp alltraps +.globl vector130 +vector130: + pushl $0 + pushl $130 + jmp alltraps +.globl vector131 +vector131: + pushl $0 + pushl $131 + jmp alltraps +.globl vector132 +vector132: + pushl $0 + pushl $132 + jmp alltraps +.globl vector133 +vector133: + pushl $0 + pushl $133 + jmp alltraps +.globl vector134 +vector134: + pushl $0 + pushl $134 + jmp alltraps +.globl vector135 +vector135: + pushl $0 + pushl $135 + jmp alltraps +.globl vector136 +vector136: + pushl $0 + pushl $136 + jmp alltraps +.globl vector137 +vector137: + pushl $0 + pushl $137 + jmp alltraps +.globl vector138 +vector138: + pushl $0 + pushl $138 + jmp alltraps +.globl vector139 +vector139: + pushl $0 + pushl $139 + jmp alltraps +.globl vector140 +vector140: + pushl $0 + pushl $140 + jmp alltraps +.globl vector141 +vector141: + pushl $0 + pushl $141 + jmp alltraps +.globl vector142 +vector142: + pushl $0 + pushl $142 + jmp alltraps +.globl vector143 +vector143: + pushl $0 + pushl $143 + jmp alltraps +.globl vector144 +vector144: + pushl $0 + pushl $144 + jmp alltraps +.globl vector145 +vector145: + pushl $0 + pushl $145 + jmp alltraps +.globl vector146 +vector146: + pushl $0 + pushl $146 + jmp alltraps +.globl vector147 +vector147: + pushl $0 + pushl $147 + jmp alltraps +.globl vector148 +vector148: + pushl $0 + pushl $148 + jmp alltraps +.globl vector149 +vector149: + pushl $0 + pushl $149 + jmp alltraps +.globl vector150 +vector150: + pushl $0 + pushl $150 + jmp alltraps +.globl vector151 +vector151: + pushl $0 + pushl $151 + jmp alltraps +.globl vector152 +vector152: + pushl $0 + pushl $152 + jmp alltraps +.globl vector153 +vector153: + pushl $0 + pushl $153 + jmp alltraps +.globl vector154 +vector154: + pushl $0 + pushl $154 + jmp alltraps +.globl vector155 +vector155: + pushl $0 + pushl $155 + jmp alltraps +.globl vector156 +vector156: + pushl $0 + pushl $156 + jmp alltraps +.globl vector157 +vector157: + pushl $0 + pushl $157 + jmp alltraps +.globl vector158 +vector158: + pushl $0 + pushl $158 + jmp alltraps +.globl vector159 +vector159: + pushl $0 + pushl $159 + jmp alltraps +.globl vector160 +vector160: + pushl $0 + pushl $160 + jmp alltraps +.globl vector161 +vector161: + pushl $0 + pushl $161 + jmp alltraps +.globl vector162 +vector162: + pushl $0 + pushl $162 + jmp alltraps +.globl vector163 +vector163: + pushl $0 + pushl $163 + jmp alltraps +.globl vector164 +vector164: + pushl $0 + pushl $164 + jmp alltraps +.globl vector165 +vector165: + pushl $0 + pushl $165 + jmp alltraps +.globl vector166 +vector166: + pushl $0 + pushl $166 + jmp alltraps +.globl vector167 +vector167: + pushl $0 + pushl $167 + jmp alltraps +.globl vector168 +vector168: + pushl $0 + pushl $168 + jmp alltraps +.globl vector169 +vector169: + pushl $0 + pushl $169 + jmp alltraps +.globl vector170 +vector170: + pushl $0 + pushl $170 + jmp alltraps +.globl vector171 +vector171: + pushl $0 + pushl $171 + jmp alltraps +.globl vector172 +vector172: + pushl $0 + pushl $172 + jmp alltraps +.globl vector173 +vector173: + pushl $0 + pushl $173 + jmp alltraps +.globl vector174 +vector174: + pushl $0 + pushl $174 + jmp alltraps +.globl vector175 +vector175: + pushl $0 + pushl $175 + jmp alltraps +.globl vector176 +vector176: + pushl $0 + pushl $176 + jmp alltraps +.globl vector177 +vector177: + pushl $0 + pushl $177 + jmp alltraps +.globl vector178 +vector178: + pushl $0 + pushl $178 + jmp alltraps +.globl vector179 +vector179: + pushl $0 + pushl $179 + jmp alltraps +.globl vector180 +vector180: + pushl $0 + pushl $180 + jmp alltraps +.globl vector181 +vector181: + pushl $0 + pushl $181 + jmp alltraps +.globl vector182 +vector182: + pushl $0 + pushl $182 + jmp alltraps +.globl vector183 +vector183: + pushl $0 + pushl $183 + jmp alltraps +.globl vector184 +vector184: + pushl $0 + pushl $184 + jmp alltraps +.globl vector185 +vector185: + pushl $0 + pushl $185 + jmp alltraps +.globl vector186 +vector186: + pushl $0 + pushl $186 + jmp alltraps +.globl vector187 +vector187: + pushl $0 + pushl $187 + jmp alltraps +.globl vector188 +vector188: + pushl $0 + pushl $188 + jmp alltraps +.globl vector189 +vector189: + pushl $0 + pushl $189 + jmp alltraps +.globl vector190 +vector190: + pushl $0 + pushl $190 + jmp alltraps +.globl vector191 +vector191: + pushl $0 + pushl $191 + jmp alltraps +.globl vector192 +vector192: + pushl $0 + pushl $192 + jmp alltraps +.globl vector193 +vector193: + pushl $0 + pushl $193 + jmp alltraps +.globl vector194 +vector194: + pushl $0 + pushl $194 + jmp alltraps +.globl vector195 +vector195: + pushl $0 + pushl $195 + jmp alltraps +.globl vector196 +vector196: + pushl $0 + pushl $196 + jmp alltraps +.globl vector197 +vector197: + pushl $0 + pushl $197 + jmp alltraps +.globl vector198 +vector198: + pushl $0 + pushl $198 + jmp alltraps +.globl vector199 +vector199: + pushl $0 + pushl $199 + jmp alltraps +.globl vector200 +vector200: + pushl $0 + pushl $200 + jmp alltraps +.globl vector201 +vector201: + pushl $0 + pushl $201 + jmp alltraps +.globl vector202 +vector202: + pushl $0 + pushl $202 + jmp alltraps +.globl vector203 +vector203: + pushl $0 + pushl $203 + jmp alltraps +.globl vector204 +vector204: + pushl $0 + pushl $204 + jmp alltraps +.globl vector205 +vector205: + pushl $0 + pushl $205 + jmp alltraps +.globl vector206 +vector206: + pushl $0 + pushl $206 + jmp alltraps +.globl vector207 +vector207: + pushl $0 + pushl $207 + jmp alltraps +.globl vector208 +vector208: + pushl $0 + pushl $208 + jmp alltraps +.globl vector209 +vector209: + pushl $0 + pushl $209 + jmp alltraps +.globl vector210 +vector210: + pushl $0 + pushl $210 + jmp alltraps +.globl vector211 +vector211: + pushl $0 + pushl $211 + jmp alltraps +.globl vector212 +vector212: + pushl $0 + pushl $212 + jmp alltraps +.globl vector213 +vector213: + pushl $0 + pushl $213 + jmp alltraps +.globl vector214 +vector214: + pushl $0 + pushl $214 + jmp alltraps +.globl vector215 +vector215: + pushl $0 + pushl $215 + jmp alltraps +.globl vector216 +vector216: + pushl $0 + pushl $216 + jmp alltraps +.globl vector217 +vector217: + pushl $0 + pushl $217 + jmp alltraps +.globl vector218 +vector218: + pushl $0 + pushl $218 + jmp alltraps +.globl vector219 +vector219: + pushl $0 + pushl $219 + jmp alltraps +.globl vector220 +vector220: + pushl $0 + pushl $220 + jmp alltraps +.globl vector221 +vector221: + pushl $0 + pushl $221 + jmp alltraps +.globl vector222 +vector222: + pushl $0 + pushl $222 + jmp alltraps +.globl vector223 +vector223: + pushl $0 + pushl $223 + jmp alltraps +.globl vector224 +vector224: + pushl $0 + pushl $224 + jmp alltraps +.globl vector225 +vector225: + pushl $0 + pushl $225 + jmp alltraps +.globl vector226 +vector226: + pushl $0 + pushl $226 + jmp alltraps +.globl vector227 +vector227: + pushl $0 + pushl $227 + jmp alltraps +.globl vector228 +vector228: + pushl $0 + pushl $228 + jmp alltraps +.globl vector229 +vector229: + pushl $0 + pushl $229 + jmp alltraps +.globl vector230 +vector230: + pushl $0 + pushl $230 + jmp alltraps +.globl vector231 +vector231: + pushl $0 + pushl $231 + jmp alltraps +.globl vector232 +vector232: + pushl $0 + pushl $232 + jmp alltraps +.globl vector233 +vector233: + pushl $0 + pushl $233 + jmp alltraps +.globl vector234 +vector234: + pushl $0 + pushl $234 + jmp alltraps +.globl vector235 +vector235: + pushl $0 + pushl $235 + jmp alltraps +.globl vector236 +vector236: + pushl $0 + pushl $236 + jmp alltraps +.globl vector237 +vector237: + pushl $0 + pushl $237 + jmp alltraps +.globl vector238 +vector238: + pushl $0 + pushl $238 + jmp alltraps +.globl vector239 +vector239: + pushl $0 + pushl $239 + jmp alltraps +.globl vector240 +vector240: + pushl $0 + pushl $240 + jmp alltraps +.globl vector241 +vector241: + pushl $0 + pushl $241 + jmp alltraps +.globl vector242 +vector242: + pushl $0 + pushl $242 + jmp alltraps +.globl vector243 +vector243: + pushl $0 + pushl $243 + jmp alltraps +.globl vector244 +vector244: + pushl $0 + pushl $244 + jmp alltraps +.globl vector245 +vector245: + pushl $0 + pushl $245 + jmp alltraps +.globl vector246 +vector246: + pushl $0 + pushl $246 + jmp alltraps +.globl vector247 +vector247: + pushl $0 + pushl $247 + jmp alltraps +.globl vector248 +vector248: + pushl $0 + pushl $248 + jmp alltraps +.globl vector249 +vector249: + pushl $0 + pushl $249 + jmp alltraps +.globl vector250 +vector250: + pushl $0 + pushl $250 + jmp alltraps +.globl vector251 +vector251: + pushl $0 + pushl $251 + jmp alltraps +.globl vector252 +vector252: + pushl $0 + pushl $252 + jmp alltraps +.globl vector253 +vector253: + pushl $0 + pushl $253 + jmp alltraps +.globl vector254 +vector254: + pushl $0 + pushl $254 + jmp alltraps +.globl vector255 +vector255: + pushl $0 + pushl $255 + jmp alltraps + +# vector table +.data +.globl vectors +vectors: + .long vector0 + .long vector1 + .long vector2 + .long vector3 + .long vector4 + .long vector5 + .long vector6 + .long vector7 + .long vector8 + .long vector9 + .long vector10 + .long vector11 + .long vector12 + .long vector13 + .long vector14 + .long vector15 + .long vector16 + .long vector17 + .long vector18 + .long vector19 + .long vector20 + .long vector21 + .long vector22 + .long vector23 + .long vector24 + .long vector25 + .long vector26 + .long vector27 + .long vector28 + .long vector29 + .long vector30 + .long vector31 + .long vector32 + .long vector33 + .long vector34 + .long vector35 + .long vector36 + .long vector37 + .long vector38 + .long vector39 + .long vector40 + .long vector41 + .long vector42 + .long vector43 + .long vector44 + .long vector45 + .long vector46 + .long vector47 + .long vector48 + .long vector49 + .long vector50 + .long vector51 + .long vector52 + .long vector53 + .long vector54 + .long vector55 + .long vector56 + .long vector57 + .long vector58 + .long vector59 + .long vector60 + .long vector61 + .long vector62 + .long vector63 + .long vector64 + .long vector65 + .long vector66 + .long vector67 + .long vector68 + .long vector69 + .long vector70 + .long vector71 + .long vector72 + .long vector73 + .long vector74 + .long vector75 + .long vector76 + .long vector77 + .long vector78 + .long vector79 + .long vector80 + .long vector81 + .long vector82 + .long vector83 + .long vector84 + .long vector85 + .long vector86 + .long vector87 + .long vector88 + .long vector89 + .long vector90 + .long vector91 + .long vector92 + .long vector93 + .long vector94 + .long vector95 + .long vector96 + .long vector97 + .long vector98 + .long vector99 + .long vector100 + .long vector101 + .long vector102 + .long vector103 + .long vector104 + .long vector105 + .long vector106 + .long vector107 + .long vector108 + .long vector109 + .long vector110 + .long vector111 + .long vector112 + .long vector113 + .long vector114 + .long vector115 + .long vector116 + .long vector117 + .long vector118 + .long vector119 + .long vector120 + .long vector121 + .long vector122 + .long vector123 + .long vector124 + .long vector125 + .long vector126 + .long vector127 + .long vector128 + .long vector129 + .long vector130 + .long vector131 + .long vector132 + .long vector133 + .long vector134 + .long vector135 + .long vector136 + .long vector137 + .long vector138 + .long vector139 + .long vector140 + .long vector141 + .long vector142 + .long vector143 + .long vector144 + .long vector145 + .long vector146 + .long vector147 + .long vector148 + .long vector149 + .long vector150 + .long vector151 + .long vector152 + .long vector153 + .long vector154 + .long vector155 + .long vector156 + .long vector157 + .long vector158 + .long vector159 + .long vector160 + .long vector161 + .long vector162 + .long vector163 + .long vector164 + .long vector165 + .long vector166 + .long vector167 + .long vector168 + .long vector169 + .long vector170 + .long vector171 + .long vector172 + .long vector173 + .long vector174 + .long vector175 + .long vector176 + .long vector177 + .long vector178 + .long vector179 + .long vector180 + .long vector181 + .long vector182 + .long vector183 + .long vector184 + .long vector185 + .long vector186 + .long vector187 + .long vector188 + .long vector189 + .long vector190 + .long vector191 + .long vector192 + .long vector193 + .long vector194 + .long vector195 + .long vector196 + .long vector197 + .long vector198 + .long vector199 + .long vector200 + .long vector201 + .long vector202 + .long vector203 + .long vector204 + .long vector205 + .long vector206 + .long vector207 + .long vector208 + .long vector209 + .long vector210 + .long vector211 + .long vector212 + .long vector213 + .long vector214 + .long vector215 + .long vector216 + .long vector217 + .long vector218 + .long vector219 + .long vector220 + .long vector221 + .long vector222 + .long vector223 + .long vector224 + .long vector225 + .long vector226 + .long vector227 + .long vector228 + .long vector229 + .long vector230 + .long vector231 + .long vector232 + .long vector233 + .long vector234 + .long vector235 + .long vector236 + .long vector237 + .long vector238 + .long vector239 + .long vector240 + .long vector241 + .long vector242 + .long vector243 + .long vector244 + .long vector245 + .long vector246 + .long vector247 + .long vector248 + .long vector249 + .long vector250 + .long vector251 + .long vector252 + .long vector253 + .long vector254 + .long vector255 diff --git a/vectors.o b/vectors.o new file mode 100644 index 0000000..6e18ee3 Binary files /dev/null and b/vectors.o differ diff --git a/vectors.pl b/vectors.pl new file mode 100644 index 0000000..57b49dd --- /dev/null +++ b/vectors.pl @@ -0,0 +1,47 @@ +#!/usr/bin/perl -w + +# Generate vectors.S, the trap/interrupt entry points. +# There has to be one entry point per interrupt number +# since otherwise there's no way for trap() to discover +# the interrupt number. + +print "# generated by vectors.pl - do not edit\n"; +print "# handlers\n"; +print ".globl alltraps\n"; +for(my $i = 0; $i < 256; $i++){ + print ".globl vector$i\n"; + print "vector$i:\n"; + if(!($i == 8 || ($i >= 10 && $i <= 14) || $i == 17)){ + print " pushl \$0\n"; + } + print " pushl \$$i\n"; + print " jmp alltraps\n"; +} + +print "\n# vector table\n"; +print ".data\n"; +print ".globl vectors\n"; +print "vectors:\n"; +for(my $i = 0; $i < 256; $i++){ + print " .long vector$i\n"; +} + +# sample output: +# # handlers +# .globl alltraps +# .globl vector0 +# vector0: +# pushl $0 +# pushl $0 +# jmp alltraps +# ... +# +# # vector table +# .data +# .globl vectors +# vectors: +# .long vector0 +# .long vector1 +# .long vector2 +# ... + diff --git a/vm.c b/vm.c new file mode 100644 index 0000000..5ac4945 --- /dev/null +++ b/vm.c @@ -0,0 +1,392 @@ +#include "param.h" +#include "types.h" +#include "defs.h" +#include "x86.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "elf.h" + +extern char data[]; // defined by kernel.ld +pde_t *kpgdir; // for use in scheduler() + +// Set up CPU's kernel segment descriptors. +// Run once on entry on each CPU. +void seginit(void) { + struct cpu *c; + + // Map "logical" addresses to virtual addresses using identity map. + // Cannot share a CODE descriptor for both kernel and user + // because it would have to have DPL_USR, but the CPU forbids + // an interrupt from CPL=0 to DPL=3. + c = &cpus[cpuid()]; + c->gdt[SEG_KCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, 0); + c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); + c->gdt[SEG_UCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, DPL_USER); + c->gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER); + lgdt(c->gdt, sizeof(c->gdt)); +} + +// Return the address of the PTE in page table pgdir +// that corresponds to virtual address va. If alloc!=0, +// create any required page table pages. +static pte_t * walkpgdir(pde_t *pgdir, const void *va, int alloc) { + pde_t *pde; + pte_t *pgtab; + + pde = &pgdir[PDX(va)]; + if (*pde & PTE_P) { + pgtab = (pte_t*)P2V(PTE_ADDR(*pde)); + } + else { + if (!alloc || (pgtab = (pte_t*)kalloc()) == 0) { + return 0; + } + // Make sure all those PTE_P bits are zero. + memset(pgtab, 0, PGSIZE); + // The permissions here are overly generous, but they can + // be further restricted by the permissions in the page table + // entries, if necessary. + *pde = V2P(pgtab) | PTE_P | PTE_W | PTE_U; + } + return &pgtab[PTX(va)]; +} + +// Create PTEs for virtual addresses starting at va that refer to +// physical addresses starting at pa. va and size might not +// be page-aligned. +static int mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm) { + char *a, *last; + pte_t *pte; + + a = (char*)PGROUNDDOWN((uint)va); + last = (char*)PGROUNDDOWN(((uint)va) + size - 1); + for (;;) { + if ((pte = walkpgdir(pgdir, a, 1)) == 0) { + return -1; + } + if (*pte & PTE_P) { + panic("remap"); + } + *pte = pa | perm | PTE_P; + if (a == last) { + break; + } + a += PGSIZE; + pa += PGSIZE; + } + return 0; +} + +// There is one page table per process, plus one that's used when +// a CPU is not running any process (kpgdir). The kernel uses the +// current process's page table during system calls and interrupts; +// page protection bits prevent user code from using the kernel's +// mappings. +// +// setupkvm() and exec() set up every page table like this: +// +// 0..KERNBASE: user memory (text+data+stack+heap), mapped to +// phys memory allocated by the kernel +// KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (for I/O space) +// KERNBASE+EXTMEM..data: mapped to EXTMEM..V2P(data) +// for the kernel's instructions and r/o data +// data..KERNBASE+PHYSTOP: mapped to V2P(data)..PHYSTOP, +// rw data + free physical memory +// 0xfe000000..0: mapped direct (devices such as ioapic) +// +// The kernel allocates physical memory for its heap and for user memory +// between V2P(end) and the end of physical memory (PHYSTOP) +// (directly addressable from end..P2V(PHYSTOP)). + +// This table defines the kernel's mappings, which are present in +// every process's page table. +static struct kmap { + void *virt; + uint phys_start; + uint phys_end; + int perm; +} kmap[] = { + { (void*)KERNBASE, 0, EXTMEM, PTE_W}, // I/O space + { (void*)KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kern text+rodata + { (void*)data, V2P(data), PHYSTOP, PTE_W}, // kern data+memory + { (void*)DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices +}; + +// Set up kernel part of a page table. +pde_t*setupkvm(void) { + pde_t *pgdir; + struct kmap *k; + + if ((pgdir = (pde_t*)kalloc()) == 0) { + return 0; + } + memset(pgdir, 0, PGSIZE); + if (P2V(PHYSTOP) > (void*)DEVSPACE) { + panic("PHYSTOP too high"); + } + for (k = kmap; k < &kmap[NELEM(kmap)]; k++) { + if (mappages(pgdir, k->virt, k->phys_end - k->phys_start, + (uint)k->phys_start, k->perm) < 0) { + freevm(pgdir); + return 0; + } + } + return pgdir; +} + +// Allocate one page table for the machine for the kernel address +// space for scheduler processes. +void kvmalloc(void) { + kpgdir = setupkvm(); + switchkvm(); +} + +// Switch h/w page table register to the kernel-only page table, +// for when no process is running. +void switchkvm(void) { + lcr3(V2P(kpgdir)); // switch to the kernel page table +} + +// Switch TSS and h/w page table to correspond to process p. +void switchuvm(struct proc *p) { + if (p == 0) { + panic("switchuvm: no process"); + } + if (p->kstack == 0) { + panic("switchuvm: no kstack"); + } + if (p->pgdir == 0) { + panic("switchuvm: no pgdir"); + } + + pushcli(); + mycpu()->gdt[SEG_TSS] = SEG16(STS_T32A, &mycpu()->ts, + sizeof(mycpu()->ts) - 1, 0); + mycpu()->gdt[SEG_TSS].s = 0; + mycpu()->ts.ss0 = SEG_KDATA << 3; + mycpu()->ts.esp0 = (uint)p->kstack + KSTACKSIZE; + // setting IOPL=0 in eflags *and* iomb beyond the tss segment limit + // forbids I/O instructions (e.g., inb and outb) from user space + mycpu()->ts.iomb = (ushort) 0xFFFF; + ltr(SEG_TSS << 3); + lcr3(V2P(p->pgdir)); // switch to process's address space + popcli(); +} + +// Load the initcode into address 0 of pgdir. +// sz must be less than a page. +void inituvm(pde_t *pgdir, char *init, uint sz) { + char *mem; + + if (sz >= PGSIZE) { + panic("inituvm: more than a page"); + } + mem = kalloc(); + memset(mem, 0, PGSIZE); + mappages(pgdir, 0, PGSIZE, V2P(mem), PTE_W | PTE_U); + memmove(mem, init, sz); +} + +// Load a program segment into pgdir. addr must be page-aligned +// and the pages from addr to addr+sz must already be mapped. +int loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz) { + uint i, pa, n; + pte_t *pte; + + if ((uint) addr % PGSIZE != 0) { + panic("loaduvm: addr must be page aligned"); + } + for (i = 0; i < sz; i += PGSIZE) { + if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) { + panic("loaduvm: address should exist"); + } + pa = PTE_ADDR(*pte); + if (sz - i < PGSIZE) { + n = sz - i; + } + else { + n = PGSIZE; + } + if (readi(ip, P2V(pa), offset + i, n) != n) { + return -1; + } + } + return 0; +} + +// Allocate page tables and physical memory to grow process from oldsz to +// newsz, which need not be page aligned. Returns new size or 0 on error. +int allocuvm(pde_t *pgdir, uint oldsz, uint newsz) { + char *mem; + uint a; + + if (newsz >= KERNBASE) { + return 0; + } + if (newsz < oldsz) { + return oldsz; + } + + a = PGROUNDUP(oldsz); + for (; a < newsz; a += PGSIZE) { + mem = kalloc(); + if (mem == 0) { + cprintf("allocuvm out of memory\n"); + deallocuvm(pgdir, newsz, oldsz); + return 0; + } + memset(mem, 0, PGSIZE); + if (mappages(pgdir, (char*)a, PGSIZE, V2P(mem), PTE_W | PTE_U) < 0) { + cprintf("allocuvm out of memory (2)\n"); + deallocuvm(pgdir, newsz, oldsz); + kfree(mem); + return 0; + } + } + return newsz; +} + +// Deallocate user pages to bring the process size from oldsz to +// newsz. oldsz and newsz need not be page-aligned, nor does newsz +// need to be less than oldsz. oldsz can be larger than the actual +// process size. Returns the new process size. +int deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) { + pte_t *pte; + uint a, pa; + + if (newsz >= oldsz) { + return oldsz; + } + + a = PGROUNDUP(newsz); + for (; a < oldsz; a += PGSIZE) { + pte = walkpgdir(pgdir, (char*)a, 0); + if (!pte) { + a = PGADDR(PDX(a) + 1, 0, 0) - PGSIZE; + } + else if ((*pte & PTE_P) != 0) { + pa = PTE_ADDR(*pte); + if (pa == 0) { + panic("kfree"); + } + char *v = P2V(pa); + kfree(v); + *pte = 0; + } + } + return newsz; +} + +// Free a page table and all the physical memory pages +// in the user part. +void freevm(pde_t *pgdir) { + uint i; + + if (pgdir == 0) { + panic("freevm: no pgdir"); + } + deallocuvm(pgdir, KERNBASE, 0); + for (i = 0; i < NPDENTRIES; i++) { + if (pgdir[i] & PTE_P) { + char * v = P2V(PTE_ADDR(pgdir[i])); + kfree(v); + } + } + kfree((char*)pgdir); +} + +// Clear PTE_U on a page. Used to create an inaccessible +// page beneath the user stack. +void clearpteu(pde_t *pgdir, char *uva) { + pte_t *pte; + + pte = walkpgdir(pgdir, uva, 0); + if (pte == 0) { + panic("clearpteu"); + } + *pte &= ~PTE_U; +} + +// Given a parent process's page table, create a copy +// of it for a child. +pde_t* copyuvm(pde_t *pgdir, uint sz) { + pde_t *d; + pte_t *pte; + uint pa, i, flags; + char *mem; + + if ((d = setupkvm()) == 0) { + return 0; + } + for (i = 0; i < sz; i += PGSIZE) { + if ((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) { + panic("copyuvm: pte should exist"); + } + if (!(*pte & PTE_P)) { + panic("copyuvm: page not present"); + } + pa = PTE_ADDR(*pte); + flags = PTE_FLAGS(*pte); + if ((mem = kalloc()) == 0) { + freevm(d); + return 0; + } + memmove(mem, (char*)P2V(pa), PGSIZE); + if (mappages(d, (void*)i, PGSIZE, V2P(mem), flags) < 0) { + kfree(mem); + freevm(d); + return 0; + } + } + return d; +} + + +// Map user virtual address to kernel address. +char*uva2ka(pde_t *pgdir, char *uva) { + pte_t *pte; + + pte = walkpgdir(pgdir, uva, 0); + if ((*pte & PTE_P) == 0) { + return 0; + } + if ((*pte & PTE_U) == 0) { + return 0; + } + return (char*)P2V(PTE_ADDR(*pte)); +} + +// Copy len bytes from p to user address va in page table pgdir. +// Most useful when pgdir is not the current page table. +// uva2ka ensures this only works for PTE_U pages. +int copyout(pde_t *pgdir, uint va, void *p, uint len) { + char *buf, *pa0; + uint n, va0; + + buf = (char*)p; + while (len > 0) { + va0 = (uint)PGROUNDDOWN(va); + pa0 = uva2ka(pgdir, (char*)va0); + if (pa0 == 0) { + return -1; + } + n = PGSIZE - (va - va0); + if (n > len) { + n = len; + } + memmove(pa0 + (va - va0), buf, n); + len -= n; + buf += n; + va = va0 + PGSIZE; + } + return 0; +} + + + + + + + + diff --git a/vm.d b/vm.d new file mode 100644 index 0000000..51631b1 --- /dev/null +++ b/vm.d @@ -0,0 +1,2 @@ +vm.o: vm.c /usr/include/stdc-predef.h param.h types.h defs.h x86.h \ + memlayout.h mmu.h proc.h elf.h diff --git a/vm.o b/vm.o new file mode 100644 index 0000000..74a6669 Binary files /dev/null and b/vm.o differ diff --git a/wc.asm b/wc.asm new file mode 100644 index 0000000..542f766 --- /dev/null +++ b/wc.asm @@ -0,0 +1,1307 @@ + +_wc: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: + exit(); + } + printf(1, "%d %d %d %s\n", l, w, c, name); +} + +int main(int argc, char *argv[]) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 57 push %edi + e: 56 push %esi + f: be 01 00 00 00 mov $0x1,%esi + 14: 53 push %ebx + 15: 51 push %ecx + 16: 83 ec 18 sub $0x18,%esp + 19: 8b 01 mov (%ecx),%eax + 1b: 8b 59 04 mov 0x4(%ecx),%ebx + 1e: 89 45 e4 mov %eax,-0x1c(%ebp) + 21: 83 c3 04 add $0x4,%ebx + int fd, i; + + if (argc <= 1) { + 24: 83 f8 01 cmp $0x1,%eax + 27: 7e 56 jle 7f + 29: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + wc(0, ""); + exit(); + } + + for (i = 1; i < argc; i++) { + if ((fd = open(argv[i], 0)) < 0) { + 30: 83 ec 08 sub $0x8,%esp + 33: 6a 00 push $0x0 + 35: ff 33 push (%ebx) + 37: e8 ff 03 00 00 call 43b + 3c: 83 c4 10 add $0x10,%esp + 3f: 89 c7 mov %eax,%edi + 41: 85 c0 test %eax,%eax + 43: 78 26 js 6b + printf(1, "wc: cannot open %s\n", argv[i]); + exit(); + } + wc(fd, argv[i]); + 45: 83 ec 08 sub $0x8,%esp + 48: ff 33 push (%ebx) + for (i = 1; i < argc; i++) { + 4a: 83 c6 01 add $0x1,%esi + 4d: 83 c3 04 add $0x4,%ebx + wc(fd, argv[i]); + 50: 50 push %eax + 51: e8 4a 00 00 00 call a0 + close(fd); + 56: 89 3c 24 mov %edi,(%esp) + 59: e8 0d 04 00 00 call 46b + for (i = 1; i < argc; i++) { + 5e: 83 c4 10 add $0x10,%esp + 61: 39 75 e4 cmp %esi,-0x1c(%ebp) + 64: 75 ca jne 30 + } + exit(); + 66: e8 68 03 00 00 call 3d3 + printf(1, "wc: cannot open %s\n", argv[i]); + 6b: 50 push %eax + 6c: ff 33 push (%ebx) + 6e: 68 8b 08 00 00 push $0x88b + 73: 6a 01 push $0x1 + 75: e8 c6 04 00 00 call 540 + exit(); + 7a: e8 54 03 00 00 call 3d3 + wc(0, ""); + 7f: 52 push %edx + 80: 52 push %edx + 81: 68 7d 08 00 00 push $0x87d + 86: 6a 00 push $0x0 + 88: e8 13 00 00 00 call a0 + exit(); + 8d: e8 41 03 00 00 call 3d3 + 92: 66 90 xchg %ax,%ax + 94: 66 90 xchg %ax,%ax + 96: 66 90 xchg %ax,%ax + 98: 66 90 xchg %ax,%ax + 9a: 66 90 xchg %ax,%ax + 9c: 66 90 xchg %ax,%ax + 9e: 66 90 xchg %ax,%ax + +000000a0 : +void wc(int fd, char *name) { + a0: 55 push %ebp + a1: 89 e5 mov %esp,%ebp + a3: 57 push %edi + a4: 56 push %esi + a5: 53 push %ebx + l = w = c = 0; + a6: 31 db xor %ebx,%ebx +void wc(int fd, char *name) { + a8: 83 ec 1c sub $0x1c,%esp + inword = 0; + ab: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + l = w = c = 0; + b2: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + b9: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) + while ((n = read(fd, buf, sizeof(buf))) > 0) { + c0: 83 ec 04 sub $0x4,%esp + c3: 68 00 02 00 00 push $0x200 + c8: 68 00 0c 00 00 push $0xc00 + cd: ff 75 08 push 0x8(%ebp) + d0: e8 16 03 00 00 call 3eb + d5: 83 c4 10 add $0x10,%esp + d8: 89 c6 mov %eax,%esi + da: 85 c0 test %eax,%eax + dc: 7e 62 jle 140 + for (i = 0; i < n; i++) { + de: 31 ff xor %edi,%edi + e0: eb 14 jmp f6 + e2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + inword = 0; + e8: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + for (i = 0; i < n; i++) { + ef: 83 c7 01 add $0x1,%edi + f2: 39 fe cmp %edi,%esi + f4: 74 42 je 138 + if (buf[i] == '\n') { + f6: 0f be 87 00 0c 00 00 movsbl 0xc00(%edi),%eax + l++; + fd: 31 c9 xor %ecx,%ecx + ff: 3c 0a cmp $0xa,%al + 101: 0f 94 c1 sete %cl + if (strchr(" \r\t\n\v", buf[i])) { + 104: 83 ec 08 sub $0x8,%esp + 107: 50 push %eax + l++; + 108: 01 cb add %ecx,%ebx + if (strchr(" \r\t\n\v", buf[i])) { + 10a: 68 68 08 00 00 push $0x868 + 10f: e8 4c 01 00 00 call 260 + 114: 83 c4 10 add $0x10,%esp + 117: 85 c0 test %eax,%eax + 119: 75 cd jne e8 + else if (!inword) { + 11b: 8b 55 e4 mov -0x1c(%ebp),%edx + 11e: 85 d2 test %edx,%edx + 120: 75 cd jne ef + for (i = 0; i < n; i++) { + 122: 83 c7 01 add $0x1,%edi + w++; + 125: 83 45 e0 01 addl $0x1,-0x20(%ebp) + inword = 1; + 129: c7 45 e4 01 00 00 00 movl $0x1,-0x1c(%ebp) + for (i = 0; i < n; i++) { + 130: 39 fe cmp %edi,%esi + 132: 75 c2 jne f6 + 134: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + c++; + 138: 01 75 dc add %esi,-0x24(%ebp) + 13b: eb 83 jmp c0 + 13d: 8d 76 00 lea 0x0(%esi),%esi + if (n < 0) { + 140: 75 24 jne 166 + printf(1, "%d %d %d %s\n", l, w, c, name); + 142: 83 ec 08 sub $0x8,%esp + 145: ff 75 0c push 0xc(%ebp) + 148: ff 75 dc push -0x24(%ebp) + 14b: ff 75 e0 push -0x20(%ebp) + 14e: 53 push %ebx + 14f: 68 7e 08 00 00 push $0x87e + 154: 6a 01 push $0x1 + 156: e8 e5 03 00 00 call 540 +} + 15b: 83 c4 20 add $0x20,%esp + 15e: 8d 65 f4 lea -0xc(%ebp),%esp + 161: 5b pop %ebx + 162: 5e pop %esi + 163: 5f pop %edi + 164: 5d pop %ebp + 165: c3 ret + printf(1, "wc: read error\n"); + 166: 50 push %eax + 167: 50 push %eax + 168: 68 6e 08 00 00 push $0x86e + 16d: 6a 01 push $0x1 + 16f: e8 cc 03 00 00 call 540 + exit(); + 174: e8 5a 02 00 00 call 3d3 + 179: 66 90 xchg %ax,%ax + 17b: 66 90 xchg %ax,%ax + 17d: 66 90 xchg %ax,%ax + 17f: 90 nop + +00000180 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 180: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 181: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 183: 89 e5 mov %esp,%ebp + 185: 53 push %ebx + 186: 8b 4d 08 mov 0x8(%ebp),%ecx + 189: 8b 5d 0c mov 0xc(%ebp),%ebx + 18c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 190: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 194: 88 14 01 mov %dl,(%ecx,%eax,1) + 197: 83 c0 01 add $0x1,%eax + 19a: 84 d2 test %dl,%dl + 19c: 75 f2 jne 190 + ; + } + return os; +} + 19e: 8b 5d fc mov -0x4(%ebp),%ebx + 1a1: 89 c8 mov %ecx,%eax + 1a3: c9 leave + 1a4: c3 ret + 1a5: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ac: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000001b0 : + +int strcmp(const char *p, const char *q) { + 1b0: 55 push %ebp + 1b1: 89 e5 mov %esp,%ebp + 1b3: 53 push %ebx + 1b4: 8b 55 08 mov 0x8(%ebp),%edx + 1b7: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 1ba: 0f b6 02 movzbl (%edx),%eax + 1bd: 84 c0 test %al,%al + 1bf: 75 17 jne 1d8 + 1c1: eb 3a jmp 1fd + 1c3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 1c7: 90 nop + 1c8: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 1cc: 83 c2 01 add $0x1,%edx + 1cf: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 1d2: 84 c0 test %al,%al + 1d4: 74 1a je 1f0 + p++, q++; + 1d6: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 1d8: 0f b6 19 movzbl (%ecx),%ebx + 1db: 38 c3 cmp %al,%bl + 1dd: 74 e9 je 1c8 + } + return (uchar) * p - (uchar) * q; + 1df: 29 d8 sub %ebx,%eax +} + 1e1: 8b 5d fc mov -0x4(%ebp),%ebx + 1e4: c9 leave + 1e5: c3 ret + 1e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1ed: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + 1f0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + 1f4: 31 c0 xor %eax,%eax + 1f6: 29 d8 sub %ebx,%eax +} + 1f8: 8b 5d fc mov -0x4(%ebp),%ebx + 1fb: c9 leave + 1fc: c3 ret + return (uchar) * p - (uchar) * q; + 1fd: 0f b6 19 movzbl (%ecx),%ebx + 200: 31 c0 xor %eax,%eax + 202: eb db jmp 1df + 204: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 20b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 20f: 90 nop + +00000210 : + +uint strlen(const char *s) { + 210: 55 push %ebp + 211: 89 e5 mov %esp,%ebp + 213: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + 216: 80 3a 00 cmpb $0x0,(%edx) + 219: 74 15 je 230 + 21b: 31 c0 xor %eax,%eax + 21d: 8d 76 00 lea 0x0(%esi),%esi + 220: 83 c0 01 add $0x1,%eax + 223: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + 227: 89 c1 mov %eax,%ecx + 229: 75 f5 jne 220 + ; + } + return n; +} + 22b: 89 c8 mov %ecx,%eax + 22d: 5d pop %ebp + 22e: c3 ret + 22f: 90 nop + for (n = 0; s[n]; n++) { + 230: 31 c9 xor %ecx,%ecx +} + 232: 5d pop %ebp + 233: 89 c8 mov %ecx,%eax + 235: c3 ret + 236: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 23d: 8d 76 00 lea 0x0(%esi),%esi + +00000240 : + +void* memset(void *dst, int c, uint n) { + 240: 55 push %ebp + 241: 89 e5 mov %esp,%ebp + 243: 57 push %edi + 244: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + 247: 8b 4d 10 mov 0x10(%ebp),%ecx + 24a: 8b 45 0c mov 0xc(%ebp),%eax + 24d: 89 d7 mov %edx,%edi + 24f: fc cld + 250: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 252: 8b 7d fc mov -0x4(%ebp),%edi + 255: 89 d0 mov %edx,%eax + 257: c9 leave + 258: c3 ret + 259: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000260 : + +char* strchr(const char *s, char c) { + 260: 55 push %ebp + 261: 89 e5 mov %esp,%ebp + 263: 8b 45 08 mov 0x8(%ebp),%eax + 266: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 26a: 0f b6 10 movzbl (%eax),%edx + 26d: 84 d2 test %dl,%dl + 26f: 75 12 jne 283 + 271: eb 1d jmp 290 + 273: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 277: 90 nop + 278: 0f b6 50 01 movzbl 0x1(%eax),%edx + 27c: 83 c0 01 add $0x1,%eax + 27f: 84 d2 test %dl,%dl + 281: 74 0d je 290 + if (*s == c) { + 283: 38 d1 cmp %dl,%cl + 285: 75 f1 jne 278 + return (char*)s; + } + } + return 0; +} + 287: 5d pop %ebp + 288: c3 ret + 289: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 290: 31 c0 xor %eax,%eax +} + 292: 5d pop %ebp + 293: c3 ret + 294: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 29b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 29f: 90 nop + +000002a0 : + +char* gets(char *buf, int max) { + 2a0: 55 push %ebp + 2a1: 89 e5 mov %esp,%ebp + 2a3: 57 push %edi + 2a4: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 2a5: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 2a8: 53 push %ebx + for (i = 0; i + 1 < max;) { + 2a9: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 2ab: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 2ae: eb 27 jmp 2d7 + cc = read(0, &c, 1); + 2b0: 83 ec 04 sub $0x4,%esp + 2b3: 6a 01 push $0x1 + 2b5: 57 push %edi + 2b6: 6a 00 push $0x0 + 2b8: e8 2e 01 00 00 call 3eb + if (cc < 1) { + 2bd: 83 c4 10 add $0x10,%esp + 2c0: 85 c0 test %eax,%eax + 2c2: 7e 1d jle 2e1 + break; + } + buf[i++] = c; + 2c4: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 2c8: 8b 55 08 mov 0x8(%ebp),%edx + 2cb: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 2cf: 3c 0a cmp $0xa,%al + 2d1: 74 1d je 2f0 + 2d3: 3c 0d cmp $0xd,%al + 2d5: 74 19 je 2f0 + for (i = 0; i + 1 < max;) { + 2d7: 89 de mov %ebx,%esi + 2d9: 83 c3 01 add $0x1,%ebx + 2dc: 3b 5d 0c cmp 0xc(%ebp),%ebx + 2df: 7c cf jl 2b0 + break; + } + } + buf[i] = '\0'; + 2e1: 8b 45 08 mov 0x8(%ebp),%eax + 2e4: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 2e8: 8d 65 f4 lea -0xc(%ebp),%esp + 2eb: 5b pop %ebx + 2ec: 5e pop %esi + 2ed: 5f pop %edi + 2ee: 5d pop %ebp + 2ef: c3 ret + buf[i] = '\0'; + 2f0: 8b 45 08 mov 0x8(%ebp),%eax + 2f3: 89 de mov %ebx,%esi + 2f5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 2f9: 8d 65 f4 lea -0xc(%ebp),%esp + 2fc: 5b pop %ebx + 2fd: 5e pop %esi + 2fe: 5f pop %edi + 2ff: 5d pop %ebp + 300: c3 ret + 301: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 308: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 30f: 90 nop + +00000310 : + +int stat(const char *n, struct stat *st) { + 310: 55 push %ebp + 311: 89 e5 mov %esp,%ebp + 313: 56 push %esi + 314: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 315: 83 ec 08 sub $0x8,%esp + 318: 6a 00 push $0x0 + 31a: ff 75 08 push 0x8(%ebp) + 31d: e8 19 01 00 00 call 43b + if (fd < 0) { + 322: 83 c4 10 add $0x10,%esp + 325: 85 c0 test %eax,%eax + 327: 78 27 js 350 + return -1; + } + r = fstat(fd, st); + 329: 83 ec 08 sub $0x8,%esp + 32c: ff 75 0c push 0xc(%ebp) + 32f: 89 c3 mov %eax,%ebx + 331: 50 push %eax + 332: e8 cc 00 00 00 call 403 + close(fd); + 337: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 33a: 89 c6 mov %eax,%esi + close(fd); + 33c: e8 2a 01 00 00 call 46b + return r; + 341: 83 c4 10 add $0x10,%esp +} + 344: 8d 65 f8 lea -0x8(%ebp),%esp + 347: 89 f0 mov %esi,%eax + 349: 5b pop %ebx + 34a: 5e pop %esi + 34b: 5d pop %ebp + 34c: c3 ret + 34d: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 350: be ff ff ff ff mov $0xffffffff,%esi + 355: eb ed jmp 344 + 357: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 35e: 66 90 xchg %ax,%ax + +00000360 : + +int atoi(const char *s) { + 360: 55 push %ebp + 361: 89 e5 mov %esp,%ebp + 363: 53 push %ebx + 364: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 367: 0f be 02 movsbl (%edx),%eax + 36a: 8d 48 d0 lea -0x30(%eax),%ecx + 36d: 80 f9 09 cmp $0x9,%cl + n = 0; + 370: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 375: 77 1e ja 395 + 377: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 37e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 380: 83 c2 01 add $0x1,%edx + 383: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 386: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 38a: 0f be 02 movsbl (%edx),%eax + 38d: 8d 58 d0 lea -0x30(%eax),%ebx + 390: 80 fb 09 cmp $0x9,%bl + 393: 76 eb jbe 380 + } + return n; +} + 395: 8b 5d fc mov -0x4(%ebp),%ebx + 398: 89 c8 mov %ecx,%eax + 39a: c9 leave + 39b: c3 ret + 39c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +000003a0 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 3a0: 55 push %ebp + 3a1: 89 e5 mov %esp,%ebp + 3a3: 57 push %edi + 3a4: 8b 45 10 mov 0x10(%ebp),%eax + 3a7: 8b 55 08 mov 0x8(%ebp),%edx + 3aa: 56 push %esi + 3ab: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 3ae: 85 c0 test %eax,%eax + 3b0: 7e 13 jle 3c5 + 3b2: 01 d0 add %edx,%eax + dst = vdst; + 3b4: 89 d7 mov %edx,%edi + 3b6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3bd: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 3c0: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 3c1: 39 f8 cmp %edi,%eax + 3c3: 75 fb jne 3c0 + } + return vdst; +} + 3c5: 5e pop %esi + 3c6: 89 d0 mov %edx,%eax + 3c8: 5f pop %edi + 3c9: 5d pop %ebp + 3ca: c3 ret + +000003cb : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 3cb: b8 01 00 00 00 mov $0x1,%eax + 3d0: cd 40 int $0x40 + 3d2: c3 ret + +000003d3 : +SYSCALL(exit) + 3d3: b8 02 00 00 00 mov $0x2,%eax + 3d8: cd 40 int $0x40 + 3da: c3 ret + +000003db : +SYSCALL(wait) + 3db: b8 03 00 00 00 mov $0x3,%eax + 3e0: cd 40 int $0x40 + 3e2: c3 ret + +000003e3 : +SYSCALL(pipe) + 3e3: b8 04 00 00 00 mov $0x4,%eax + 3e8: cd 40 int $0x40 + 3ea: c3 ret + +000003eb : +SYSCALL(read) + 3eb: b8 05 00 00 00 mov $0x5,%eax + 3f0: cd 40 int $0x40 + 3f2: c3 ret + +000003f3 : +SYSCALL(kill) + 3f3: b8 06 00 00 00 mov $0x6,%eax + 3f8: cd 40 int $0x40 + 3fa: c3 ret + +000003fb : +SYSCALL(exec) + 3fb: b8 07 00 00 00 mov $0x7,%eax + 400: cd 40 int $0x40 + 402: c3 ret + +00000403 : +SYSCALL(fstat) + 403: b8 08 00 00 00 mov $0x8,%eax + 408: cd 40 int $0x40 + 40a: c3 ret + +0000040b : +SYSCALL(chdir) + 40b: b8 09 00 00 00 mov $0x9,%eax + 410: cd 40 int $0x40 + 412: c3 ret + +00000413 : +SYSCALL(dup) + 413: b8 0a 00 00 00 mov $0xa,%eax + 418: cd 40 int $0x40 + 41a: c3 ret + +0000041b : +SYSCALL(getpid) + 41b: b8 0b 00 00 00 mov $0xb,%eax + 420: cd 40 int $0x40 + 422: c3 ret + +00000423 : +SYSCALL(sbrk) + 423: b8 0c 00 00 00 mov $0xc,%eax + 428: cd 40 int $0x40 + 42a: c3 ret + +0000042b : +SYSCALL(sleep) + 42b: b8 0d 00 00 00 mov $0xd,%eax + 430: cd 40 int $0x40 + 432: c3 ret + +00000433 : +SYSCALL(uptime) + 433: b8 0e 00 00 00 mov $0xe,%eax + 438: cd 40 int $0x40 + 43a: c3 ret + +0000043b : +SYSCALL(open) + 43b: b8 0f 00 00 00 mov $0xf,%eax + 440: cd 40 int $0x40 + 442: c3 ret + +00000443 : +SYSCALL(write) + 443: b8 10 00 00 00 mov $0x10,%eax + 448: cd 40 int $0x40 + 44a: c3 ret + +0000044b : +SYSCALL(mknod) + 44b: b8 11 00 00 00 mov $0x11,%eax + 450: cd 40 int $0x40 + 452: c3 ret + +00000453 : +SYSCALL(unlink) + 453: b8 12 00 00 00 mov $0x12,%eax + 458: cd 40 int $0x40 + 45a: c3 ret + +0000045b : +SYSCALL(link) + 45b: b8 13 00 00 00 mov $0x13,%eax + 460: cd 40 int $0x40 + 462: c3 ret + +00000463 : +SYSCALL(mkdir) + 463: b8 14 00 00 00 mov $0x14,%eax + 468: cd 40 int $0x40 + 46a: c3 ret + +0000046b : +SYSCALL(close) + 46b: b8 15 00 00 00 mov $0x15,%eax + 470: cd 40 int $0x40 + 472: c3 ret + +00000473 : +SYSCALL(getch) + 473: b8 16 00 00 00 mov $0x16,%eax + 478: cd 40 int $0x40 + 47a: c3 ret + +0000047b : +SYSCALL(greeting) + 47b: b8 17 00 00 00 mov $0x17,%eax + 480: cd 40 int $0x40 + 482: c3 ret + +00000483 : +SYSCALL(shutdown) + 483: b8 18 00 00 00 mov $0x18,%eax + 488: cd 40 int $0x40 + 48a: c3 ret + 48b: 66 90 xchg %ax,%ax + 48d: 66 90 xchg %ax,%ax + 48f: 90 nop + +00000490 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 490: 55 push %ebp + 491: 89 e5 mov %esp,%ebp + 493: 57 push %edi + 494: 56 push %esi + 495: 53 push %ebx + 496: 83 ec 3c sub $0x3c,%esp + 499: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 49c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 49e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 4a1: 85 d2 test %edx,%edx + 4a3: 0f 89 7f 00 00 00 jns 528 + 4a9: f6 45 08 01 testb $0x1,0x8(%ebp) + 4ad: 74 79 je 528 + neg = 1; + 4af: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 4b6: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 4b8: 31 db xor %ebx,%ebx + 4ba: 8d 75 d7 lea -0x29(%ebp),%esi + 4bd: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 4c0: 89 c8 mov %ecx,%eax + 4c2: 31 d2 xor %edx,%edx + 4c4: 89 cf mov %ecx,%edi + 4c6: f7 75 c4 divl -0x3c(%ebp) + 4c9: 0f b6 92 00 09 00 00 movzbl 0x900(%edx),%edx + 4d0: 89 45 c0 mov %eax,-0x40(%ebp) + 4d3: 89 d8 mov %ebx,%eax + 4d5: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 4d8: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 4db: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 4de: 39 7d c4 cmp %edi,-0x3c(%ebp) + 4e1: 76 dd jbe 4c0 + if (neg) { + 4e3: 8b 4d bc mov -0x44(%ebp),%ecx + 4e6: 85 c9 test %ecx,%ecx + 4e8: 74 0c je 4f6 + buf[i++] = '-'; + 4ea: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 4ef: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 4f1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 4f6: 8b 7d b8 mov -0x48(%ebp),%edi + 4f9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 4fd: eb 07 jmp 506 + 4ff: 90 nop + putc(fd, buf[i]); + 500: 0f b6 13 movzbl (%ebx),%edx + 503: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 506: 83 ec 04 sub $0x4,%esp + 509: 88 55 d7 mov %dl,-0x29(%ebp) + 50c: 6a 01 push $0x1 + 50e: 56 push %esi + 50f: 57 push %edi + 510: e8 2e ff ff ff call 443 + while (--i >= 0) { + 515: 83 c4 10 add $0x10,%esp + 518: 39 de cmp %ebx,%esi + 51a: 75 e4 jne 500 + } +} + 51c: 8d 65 f4 lea -0xc(%ebp),%esp + 51f: 5b pop %ebx + 520: 5e pop %esi + 521: 5f pop %edi + 522: 5d pop %ebp + 523: c3 ret + 524: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 528: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 52f: eb 87 jmp 4b8 + 531: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 538: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 53f: 90 nop + +00000540 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 540: 55 push %ebp + 541: 89 e5 mov %esp,%ebp + 543: 57 push %edi + 544: 56 push %esi + 545: 53 push %ebx + 546: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 549: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 54c: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 54f: 0f b6 13 movzbl (%ebx),%edx + 552: 84 d2 test %dl,%dl + 554: 74 6a je 5c0 + ap = (uint*)(void*)&fmt + 1; + 556: 8d 45 10 lea 0x10(%ebp),%eax + 559: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 55c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 55f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 561: 89 45 d0 mov %eax,-0x30(%ebp) + 564: eb 36 jmp 59c + 566: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 56d: 8d 76 00 lea 0x0(%esi),%esi + 570: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 573: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 578: 83 f8 25 cmp $0x25,%eax + 57b: 74 15 je 592 + write(fd, &c, 1); + 57d: 83 ec 04 sub $0x4,%esp + 580: 88 55 e7 mov %dl,-0x19(%ebp) + 583: 6a 01 push $0x1 + 585: 57 push %edi + 586: 56 push %esi + 587: e8 b7 fe ff ff call 443 + 58c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 58f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 592: 0f b6 13 movzbl (%ebx),%edx + 595: 83 c3 01 add $0x1,%ebx + 598: 84 d2 test %dl,%dl + 59a: 74 24 je 5c0 + c = fmt[i] & 0xff; + 59c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 59f: 85 c9 test %ecx,%ecx + 5a1: 74 cd je 570 + } + } + else if (state == '%') { + 5a3: 83 f9 25 cmp $0x25,%ecx + 5a6: 75 ea jne 592 + if (c == 'd') { + 5a8: 83 f8 25 cmp $0x25,%eax + 5ab: 0f 84 07 01 00 00 je 6b8 + 5b1: 83 e8 63 sub $0x63,%eax + 5b4: 83 f8 15 cmp $0x15,%eax + 5b7: 77 17 ja 5d0 + 5b9: ff 24 85 a8 08 00 00 jmp *0x8a8(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 5c0: 8d 65 f4 lea -0xc(%ebp),%esp + 5c3: 5b pop %ebx + 5c4: 5e pop %esi + 5c5: 5f pop %edi + 5c6: 5d pop %ebp + 5c7: c3 ret + 5c8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5cf: 90 nop + write(fd, &c, 1); + 5d0: 83 ec 04 sub $0x4,%esp + 5d3: 88 55 d4 mov %dl,-0x2c(%ebp) + 5d6: 6a 01 push $0x1 + 5d8: 57 push %edi + 5d9: 56 push %esi + 5da: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 5de: e8 60 fe ff ff call 443 + putc(fd, c); + 5e3: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 5e7: 83 c4 0c add $0xc,%esp + 5ea: 88 55 e7 mov %dl,-0x19(%ebp) + 5ed: 6a 01 push $0x1 + 5ef: 57 push %edi + 5f0: 56 push %esi + 5f1: e8 4d fe ff ff call 443 + putc(fd, c); + 5f6: 83 c4 10 add $0x10,%esp + state = 0; + 5f9: 31 c9 xor %ecx,%ecx + 5fb: eb 95 jmp 592 + 5fd: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 600: 83 ec 0c sub $0xc,%esp + 603: b9 10 00 00 00 mov $0x10,%ecx + 608: 6a 00 push $0x0 + 60a: 8b 45 d0 mov -0x30(%ebp),%eax + 60d: 8b 10 mov (%eax),%edx + 60f: 89 f0 mov %esi,%eax + 611: e8 7a fe ff ff call 490 + ap++; + 616: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 61a: 83 c4 10 add $0x10,%esp + state = 0; + 61d: 31 c9 xor %ecx,%ecx + 61f: e9 6e ff ff ff jmp 592 + 624: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 628: 8b 45 d0 mov -0x30(%ebp),%eax + 62b: 8b 10 mov (%eax),%edx + ap++; + 62d: 83 c0 04 add $0x4,%eax + 630: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 633: 85 d2 test %edx,%edx + 635: 0f 84 8d 00 00 00 je 6c8 + while (*s != 0) { + 63b: 0f b6 02 movzbl (%edx),%eax + state = 0; + 63e: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 640: 84 c0 test %al,%al + 642: 0f 84 4a ff ff ff je 592 + 648: 89 5d d4 mov %ebx,-0x2c(%ebp) + 64b: 89 d3 mov %edx,%ebx + 64d: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 650: 83 ec 04 sub $0x4,%esp + s++; + 653: 83 c3 01 add $0x1,%ebx + 656: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 659: 6a 01 push $0x1 + 65b: 57 push %edi + 65c: 56 push %esi + 65d: e8 e1 fd ff ff call 443 + while (*s != 0) { + 662: 0f b6 03 movzbl (%ebx),%eax + 665: 83 c4 10 add $0x10,%esp + 668: 84 c0 test %al,%al + 66a: 75 e4 jne 650 + state = 0; + 66c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 66f: 31 c9 xor %ecx,%ecx + 671: e9 1c ff ff ff jmp 592 + 676: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 67d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 680: 83 ec 0c sub $0xc,%esp + 683: b9 0a 00 00 00 mov $0xa,%ecx + 688: 6a 01 push $0x1 + 68a: e9 7b ff ff ff jmp 60a + 68f: 90 nop + putc(fd, *ap); + 690: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 693: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 696: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 698: 6a 01 push $0x1 + 69a: 57 push %edi + 69b: 56 push %esi + putc(fd, *ap); + 69c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 69f: e8 9f fd ff ff call 443 + ap++; + 6a4: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 6a8: 83 c4 10 add $0x10,%esp + state = 0; + 6ab: 31 c9 xor %ecx,%ecx + 6ad: e9 e0 fe ff ff jmp 592 + 6b2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 6b8: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 6bb: 83 ec 04 sub $0x4,%esp + 6be: e9 2a ff ff ff jmp 5ed + 6c3: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 6c7: 90 nop + s = "(null)"; + 6c8: ba 9f 08 00 00 mov $0x89f,%edx + while (*s != 0) { + 6cd: 89 5d d4 mov %ebx,-0x2c(%ebp) + 6d0: b8 28 00 00 00 mov $0x28,%eax + 6d5: 89 d3 mov %edx,%ebx + 6d7: e9 74 ff ff ff jmp 650 + 6dc: 66 90 xchg %ax,%ax + 6de: 66 90 xchg %ax,%ax + +000006e0 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 6e0: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 6e1: a1 00 0e 00 00 mov 0xe00,%eax +void free(void *ap) { + 6e6: 89 e5 mov %esp,%ebp + 6e8: 57 push %edi + 6e9: 56 push %esi + 6ea: 53 push %ebx + 6eb: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 6ee: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 6f1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 6f8: 89 c2 mov %eax,%edx + 6fa: 8b 00 mov (%eax),%eax + 6fc: 39 ca cmp %ecx,%edx + 6fe: 73 30 jae 730 + 700: 39 c1 cmp %eax,%ecx + 702: 72 04 jb 708 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 704: 39 c2 cmp %eax,%edx + 706: 72 f0 jb 6f8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 708: 8b 73 fc mov -0x4(%ebx),%esi + 70b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 70e: 39 f8 cmp %edi,%eax + 710: 74 30 je 742 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 712: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 715: 8b 42 04 mov 0x4(%edx),%eax + 718: 8d 34 c2 lea (%edx,%eax,8),%esi + 71b: 39 f1 cmp %esi,%ecx + 71d: 74 3a je 759 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 71f: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 721: 5b pop %ebx + freep = p; + 722: 89 15 00 0e 00 00 mov %edx,0xe00 +} + 728: 5e pop %esi + 729: 5f pop %edi + 72a: 5d pop %ebp + 72b: c3 ret + 72c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 730: 39 c2 cmp %eax,%edx + 732: 72 c4 jb 6f8 + 734: 39 c1 cmp %eax,%ecx + 736: 73 c0 jae 6f8 + if (bp + bp->s.size == p->s.ptr) { + 738: 8b 73 fc mov -0x4(%ebx),%esi + 73b: 8d 3c f1 lea (%ecx,%esi,8),%edi + 73e: 39 f8 cmp %edi,%eax + 740: 75 d0 jne 712 + bp->s.size += p->s.ptr->s.size; + 742: 03 70 04 add 0x4(%eax),%esi + 745: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 748: 8b 02 mov (%edx),%eax + 74a: 8b 00 mov (%eax),%eax + 74c: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 74f: 8b 42 04 mov 0x4(%edx),%eax + 752: 8d 34 c2 lea (%edx,%eax,8),%esi + 755: 39 f1 cmp %esi,%ecx + 757: 75 c6 jne 71f + p->s.size += bp->s.size; + 759: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 75c: 89 15 00 0e 00 00 mov %edx,0xe00 + p->s.size += bp->s.size; + 762: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 765: 8b 4b f8 mov -0x8(%ebx),%ecx + 768: 89 0a mov %ecx,(%edx) +} + 76a: 5b pop %ebx + 76b: 5e pop %esi + 76c: 5f pop %edi + 76d: 5d pop %ebp + 76e: c3 ret + 76f: 90 nop + +00000770 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 770: 55 push %ebp + 771: 89 e5 mov %esp,%ebp + 773: 57 push %edi + 774: 56 push %esi + 775: 53 push %ebx + 776: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 779: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 77c: 8b 3d 00 0e 00 00 mov 0xe00,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 782: 8d 70 07 lea 0x7(%eax),%esi + 785: c1 ee 03 shr $0x3,%esi + 788: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 78b: 85 ff test %edi,%edi + 78d: 0f 84 9d 00 00 00 je 830 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 793: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 795: 8b 4a 04 mov 0x4(%edx),%ecx + 798: 39 f1 cmp %esi,%ecx + 79a: 73 6a jae 806 + 79c: bb 00 10 00 00 mov $0x1000,%ebx + 7a1: 39 de cmp %ebx,%esi + 7a3: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 7a6: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 7ad: 89 45 e4 mov %eax,-0x1c(%ebp) + 7b0: eb 17 jmp 7c9 + 7b2: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 7b8: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 7ba: 8b 48 04 mov 0x4(%eax),%ecx + 7bd: 39 f1 cmp %esi,%ecx + 7bf: 73 4f jae 810 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 7c1: 8b 3d 00 0e 00 00 mov 0xe00,%edi + 7c7: 89 c2 mov %eax,%edx + 7c9: 39 d7 cmp %edx,%edi + 7cb: 75 eb jne 7b8 + p = sbrk(nu * sizeof(Header)); + 7cd: 83 ec 0c sub $0xc,%esp + 7d0: ff 75 e4 push -0x1c(%ebp) + 7d3: e8 4b fc ff ff call 423 + if (p == (char*)-1) { + 7d8: 83 c4 10 add $0x10,%esp + 7db: 83 f8 ff cmp $0xffffffff,%eax + 7de: 74 1c je 7fc + hp->s.size = nu; + 7e0: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 7e3: 83 ec 0c sub $0xc,%esp + 7e6: 83 c0 08 add $0x8,%eax + 7e9: 50 push %eax + 7ea: e8 f1 fe ff ff call 6e0 + return freep; + 7ef: 8b 15 00 0e 00 00 mov 0xe00,%edx + if ((p = morecore(nunits)) == 0) { + 7f5: 83 c4 10 add $0x10,%esp + 7f8: 85 d2 test %edx,%edx + 7fa: 75 bc jne 7b8 + return 0; + } + } + } +} + 7fc: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 7ff: 31 c0 xor %eax,%eax +} + 801: 5b pop %ebx + 802: 5e pop %esi + 803: 5f pop %edi + 804: 5d pop %ebp + 805: c3 ret + if (p->s.size >= nunits) { + 806: 89 d0 mov %edx,%eax + 808: 89 fa mov %edi,%edx + 80a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 810: 39 ce cmp %ecx,%esi + 812: 74 4c je 860 + p->s.size -= nunits; + 814: 29 f1 sub %esi,%ecx + 816: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 819: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 81c: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 81f: 89 15 00 0e 00 00 mov %edx,0xe00 +} + 825: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 828: 83 c0 08 add $0x8,%eax +} + 82b: 5b pop %ebx + 82c: 5e pop %esi + 82d: 5f pop %edi + 82e: 5d pop %ebp + 82f: c3 ret + base.s.ptr = freep = prevp = &base; + 830: c7 05 00 0e 00 00 04 movl $0xe04,0xe00 + 837: 0e 00 00 + base.s.size = 0; + 83a: bf 04 0e 00 00 mov $0xe04,%edi + base.s.ptr = freep = prevp = &base; + 83f: c7 05 04 0e 00 00 04 movl $0xe04,0xe04 + 846: 0e 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 849: 89 fa mov %edi,%edx + base.s.size = 0; + 84b: c7 05 08 0e 00 00 00 movl $0x0,0xe08 + 852: 00 00 00 + if (p->s.size >= nunits) { + 855: e9 42 ff ff ff jmp 79c + 85a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 860: 8b 08 mov (%eax),%ecx + 862: 89 0a mov %ecx,(%edx) + 864: eb b9 jmp 81f diff --git a/wc.c b/wc.c new file mode 100644 index 0000000..0869cf8 --- /dev/null +++ b/wc.c @@ -0,0 +1,52 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +char buf[512]; + +void wc(int fd, char *name) { + int i, n; + int l, w, c, inword; + + l = w = c = 0; + inword = 0; + while ((n = read(fd, buf, sizeof(buf))) > 0) { + for (i = 0; i < n; i++) { + c++; + if (buf[i] == '\n') { + l++; + } + if (strchr(" \r\t\n\v", buf[i])) { + inword = 0; + } + else if (!inword) { + w++; + inword = 1; + } + } + } + if (n < 0) { + printf(1, "wc: read error\n"); + exit(); + } + printf(1, "%d %d %d %s\n", l, w, c, name); +} + +int main(int argc, char *argv[]) { + int fd, i; + + if (argc <= 1) { + wc(0, ""); + exit(); + } + + for (i = 1; i < argc; i++) { + if ((fd = open(argv[i], 0)) < 0) { + printf(1, "wc: cannot open %s\n", argv[i]); + exit(); + } + wc(fd, argv[i]); + close(fd); + } + exit(); +} diff --git a/wc.d b/wc.d new file mode 100644 index 0000000..6adc498 --- /dev/null +++ b/wc.d @@ -0,0 +1 @@ +wc.o: wc.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/wc.o b/wc.o new file mode 100644 index 0000000..006f57a Binary files /dev/null and b/wc.o differ diff --git a/wc.sym b/wc.sym new file mode 100644 index 0000000..11f6258 --- /dev/null +++ b/wc.sym @@ -0,0 +1,50 @@ +00000000 wc.c +00000000 ulib.c +00000000 printf.c +00000490 printint +00000900 digits.0 +00000000 umalloc.c +00000e00 freep +00000e04 base +00000180 strcpy +00000540 printf +0000047b greeting +000003a0 memmove +0000044b mknod +000002a0 gets +0000041b getpid +00000770 malloc +0000042b sleep +000003e3 pipe +00000473 getch +00000443 write +00000403 fstat +000003f3 kill +0000040b chdir +000003fb exec +000003db wait +000003eb read +00000453 unlink +000000a0 wc +000003cb fork +00000423 sbrk +00000433 uptime +00000be8 __bss_start +00000240 memset +00000000 main +000001b0 strcmp +00000483 shutdown +00000413 dup +00000c00 buf +00000310 stat +00000be8 _edata +00000e0c _end +0000045b link +000003d3 exit +00000360 atoi +00000210 strlen +0000043b open +00000260 strchr +00000463 mkdir +0000046b close +000006e0 free diff --git a/x86.h b/x86.h new file mode 100644 index 0000000..118f725 --- /dev/null +++ b/x86.h @@ -0,0 +1,148 @@ +// Routines to let C code use special x86 instructions. + +static inline uchar inb(ushort port) { + uchar data; + + asm volatile ("in %1,%0" : "=a" (data) : "d" (port)); + return data; +} + +static inline void insl(int port, void *addr, int cnt) { + asm volatile ("cld; rep insl" : + "=D" (addr), "=c" (cnt) : + "d" (port), "0" (addr), "1" (cnt) : + "memory", "cc"); +} + +static inline void outb(ushort port, uchar data) { + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +} + +static inline void outw(ushort port, ushort data) { + asm volatile ("out %0,%1" : : "a" (data), "d" (port)); +} + +static inline void outsl(int port, const void *addr, int cnt) { + asm volatile ("cld; rep outsl" : + "=S" (addr), "=c" (cnt) : + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + "=D" (addr), "=c" (cnt) : + "0" (addr), "1" (cnt), "a" (data) : + "memory", "cc"); +} + +static inline void stosl(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosl" : + "=D" (addr), "=c" (cnt) : + "0" (addr), "1" (cnt), "a" (data) : + "memory", "cc"); +} + +struct segdesc; + +static inline void lgdt(struct segdesc *p, int size) { + volatile ushort pd[3]; + + pd[0] = size - 1; + pd[1] = (uint)p; + pd[2] = (uint)p >> 16; + + asm volatile ("lgdt (%0)" : : "r" (pd)); +} + +struct gatedesc; + +static inline void lidt(struct gatedesc *p, int size) { + volatile ushort pd[3]; + + pd[0] = size - 1; + pd[1] = (uint)p; + pd[2] = (uint)p >> 16; + + asm volatile ("lidt (%0)" : : "r" (pd)); +} + +static inline void ltr(ushort sel) { + asm volatile ("ltr %0" : : "r" (sel)); +} + +static inline uint readeflags(void) { + uint eflags; + asm volatile ("pushfl; popl %0" : "=r" (eflags)); + return eflags; +} + +static inline void loadgs(ushort v) { + asm volatile ("movw %0, %%gs" : : "r" (v)); +} + +static inline void cli(void) { + asm volatile ("cli"); +} + +static inline void sti(void) { + asm volatile ("sti"); +} + +static inline uint xchg(volatile uint *addr, uint newval) { + uint result; + + // The + in "+m" denotes a read-modify-write operand. + asm volatile ("lock; xchgl %0, %1" : + "+m" (*addr), "=a" (result) : + "1" (newval) : + "cc"); + return result; +} + +static inline uint rcr2(void) { + uint val; + asm volatile ("movl %%cr2,%0" : "=r" (val)); + return val; +} + +static inline void lcr3(uint val) { + asm volatile ("movl %0,%%cr3" : : "r" (val)); +} + +// Layout of the trap frame built on the stack by the +// hardware and by trapasm.S, and passed to trap(). +struct trapframe { + // registers as pushed by pusha + uint edi; + uint esi; + uint ebp; + uint oesp; // useless & ignored + uint ebx; + uint edx; + uint ecx; + uint eax; + + // rest of trap frame + ushort gs; + ushort padding1; + ushort fs; + ushort padding2; + ushort es; + ushort padding3; + ushort ds; + ushort padding4; + uint trapno; + + // below here defined by x86 hardware + uint err; + uint eip; + ushort cs; + ushort padding5; + uint eflags; + + // below here only when crossing rings, such as from user to kernel + uint esp; + ushort ss; + ushort padding6; +}; diff --git a/xv6.img b/xv6.img new file mode 100644 index 0000000..a6a5e93 --- /dev/null +++ b/xv6.img @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18ee787bf99126dedbb0a9500ddf41d80a5ab1004c67d14dddc0a84c460cb340 +size 5120000 diff --git a/zombie.asm b/zombie.asm new file mode 100644 index 0000000..3b916c8 --- /dev/null +++ b/zombie.asm @@ -0,0 +1,1145 @@ + +_zombie: file format elf32-i386 + + +Disassembly of section .text: + +00000000
: + +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(void) { + 0: 8d 4c 24 04 lea 0x4(%esp),%ecx + 4: 83 e4 f0 and $0xfffffff0,%esp + 7: ff 71 fc push -0x4(%ecx) + a: 55 push %ebp + b: 89 e5 mov %esp,%ebp + d: 51 push %ecx + e: 83 ec 04 sub $0x4,%esp + if (fork() > 0) { + 11: e8 65 02 00 00 call 27b + 16: 85 c0 test %eax,%eax + 18: 7e 0d jle 27 + sleep(5); // Let child exit before parent. + 1a: 83 ec 0c sub $0xc,%esp + 1d: 6a 05 push $0x5 + 1f: e8 b7 02 00 00 call 2db + 24: 83 c4 10 add $0x10,%esp + } + exit(); + 27: e8 57 02 00 00 call 283 + 2c: 66 90 xchg %ax,%ax + 2e: 66 90 xchg %ax,%ax + +00000030 : +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "x86.h" + +char*strcpy(char *s, const char *t) { + 30: 55 push %ebp + char *os; + + os = s; + while ((*s++ = *t++) != 0) { + 31: 31 c0 xor %eax,%eax +char*strcpy(char *s, const char *t) { + 33: 89 e5 mov %esp,%ebp + 35: 53 push %ebx + 36: 8b 4d 08 mov 0x8(%ebp),%ecx + 39: 8b 5d 0c mov 0xc(%ebp),%ebx + 3c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + while ((*s++ = *t++) != 0) { + 40: 0f b6 14 03 movzbl (%ebx,%eax,1),%edx + 44: 88 14 01 mov %dl,(%ecx,%eax,1) + 47: 83 c0 01 add $0x1,%eax + 4a: 84 d2 test %dl,%dl + 4c: 75 f2 jne 40 + ; + } + return os; +} + 4e: 8b 5d fc mov -0x4(%ebp),%ebx + 51: 89 c8 mov %ecx,%eax + 53: c9 leave + 54: c3 ret + 55: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000060 : + +int strcmp(const char *p, const char *q) { + 60: 55 push %ebp + 61: 89 e5 mov %esp,%ebp + 63: 53 push %ebx + 64: 8b 55 08 mov 0x8(%ebp),%edx + 67: 8b 4d 0c mov 0xc(%ebp),%ecx + while (*p && *p == *q) { + 6a: 0f b6 02 movzbl (%edx),%eax + 6d: 84 c0 test %al,%al + 6f: 75 17 jne 88 + 71: eb 3a jmp ad + 73: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 77: 90 nop + 78: 0f b6 42 01 movzbl 0x1(%edx),%eax + p++, q++; + 7c: 83 c2 01 add $0x1,%edx + 7f: 8d 59 01 lea 0x1(%ecx),%ebx + while (*p && *p == *q) { + 82: 84 c0 test %al,%al + 84: 74 1a je a0 + p++, q++; + 86: 89 d9 mov %ebx,%ecx + while (*p && *p == *q) { + 88: 0f b6 19 movzbl (%ecx),%ebx + 8b: 38 c3 cmp %al,%bl + 8d: 74 e9 je 78 + } + return (uchar) * p - (uchar) * q; + 8f: 29 d8 sub %ebx,%eax +} + 91: 8b 5d fc mov -0x4(%ebp),%ebx + 94: c9 leave + 95: c3 ret + 96: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 9d: 8d 76 00 lea 0x0(%esi),%esi + return (uchar) * p - (uchar) * q; + a0: 0f b6 59 01 movzbl 0x1(%ecx),%ebx + a4: 31 c0 xor %eax,%eax + a6: 29 d8 sub %ebx,%eax +} + a8: 8b 5d fc mov -0x4(%ebp),%ebx + ab: c9 leave + ac: c3 ret + return (uchar) * p - (uchar) * q; + ad: 0f b6 19 movzbl (%ecx),%ebx + b0: 31 c0 xor %eax,%eax + b2: eb db jmp 8f + b4: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + bb: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + bf: 90 nop + +000000c0 : + +uint strlen(const char *s) { + c0: 55 push %ebp + c1: 89 e5 mov %esp,%ebp + c3: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + for (n = 0; s[n]; n++) { + c6: 80 3a 00 cmpb $0x0,(%edx) + c9: 74 15 je e0 + cb: 31 c0 xor %eax,%eax + cd: 8d 76 00 lea 0x0(%esi),%esi + d0: 83 c0 01 add $0x1,%eax + d3: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1) + d7: 89 c1 mov %eax,%ecx + d9: 75 f5 jne d0 + ; + } + return n; +} + db: 89 c8 mov %ecx,%eax + dd: 5d pop %ebp + de: c3 ret + df: 90 nop + for (n = 0; s[n]; n++) { + e0: 31 c9 xor %ecx,%ecx +} + e2: 5d pop %ebp + e3: 89 c8 mov %ecx,%eax + e5: c3 ret + e6: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + ed: 8d 76 00 lea 0x0(%esi),%esi + +000000f0 : + +void* memset(void *dst, int c, uint n) { + f0: 55 push %ebp + f1: 89 e5 mov %esp,%ebp + f3: 57 push %edi + f4: 8b 55 08 mov 0x8(%ebp),%edx + "d" (port), "0" (addr), "1" (cnt) : + "cc"); +} + +static inline void stosb(void *addr, int data, int cnt) { + asm volatile ("cld; rep stosb" : + f7: 8b 4d 10 mov 0x10(%ebp),%ecx + fa: 8b 45 0c mov 0xc(%ebp),%eax + fd: 89 d7 mov %edx,%edi + ff: fc cld + 100: f3 aa rep stos %al,%es:(%edi) + stosb(dst, c, n); + return dst; +} + 102: 8b 7d fc mov -0x4(%ebp),%edi + 105: 89 d0 mov %edx,%eax + 107: c9 leave + 108: c3 ret + 109: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + +00000110 : + +char* strchr(const char *s, char c) { + 110: 55 push %ebp + 111: 89 e5 mov %esp,%ebp + 113: 8b 45 08 mov 0x8(%ebp),%eax + 116: 0f b6 4d 0c movzbl 0xc(%ebp),%ecx + for (; *s; s++) { + 11a: 0f b6 10 movzbl (%eax),%edx + 11d: 84 d2 test %dl,%dl + 11f: 75 12 jne 133 + 121: eb 1d jmp 140 + 123: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 127: 90 nop + 128: 0f b6 50 01 movzbl 0x1(%eax),%edx + 12c: 83 c0 01 add $0x1,%eax + 12f: 84 d2 test %dl,%dl + 131: 74 0d je 140 + if (*s == c) { + 133: 38 d1 cmp %dl,%cl + 135: 75 f1 jne 128 + return (char*)s; + } + } + return 0; +} + 137: 5d pop %ebp + 138: c3 ret + 139: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + return 0; + 140: 31 c0 xor %eax,%eax +} + 142: 5d pop %ebp + 143: c3 ret + 144: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 14b: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 14f: 90 nop + +00000150 : + +char* gets(char *buf, int max) { + 150: 55 push %ebp + 151: 89 e5 mov %esp,%ebp + 153: 57 push %edi + 154: 56 push %esi + int i, cc; + char c; + + for (i = 0; i + 1 < max;) { + cc = read(0, &c, 1); + 155: 8d 7d e7 lea -0x19(%ebp),%edi +char* gets(char *buf, int max) { + 158: 53 push %ebx + for (i = 0; i + 1 < max;) { + 159: 31 db xor %ebx,%ebx +char* gets(char *buf, int max) { + 15b: 83 ec 1c sub $0x1c,%esp + for (i = 0; i + 1 < max;) { + 15e: eb 27 jmp 187 + cc = read(0, &c, 1); + 160: 83 ec 04 sub $0x4,%esp + 163: 6a 01 push $0x1 + 165: 57 push %edi + 166: 6a 00 push $0x0 + 168: e8 2e 01 00 00 call 29b + if (cc < 1) { + 16d: 83 c4 10 add $0x10,%esp + 170: 85 c0 test %eax,%eax + 172: 7e 1d jle 191 + break; + } + buf[i++] = c; + 174: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 178: 8b 55 08 mov 0x8(%ebp),%edx + 17b: 88 44 1a ff mov %al,-0x1(%edx,%ebx,1) + if (c == '\n' || c == '\r') { + 17f: 3c 0a cmp $0xa,%al + 181: 74 1d je 1a0 + 183: 3c 0d cmp $0xd,%al + 185: 74 19 je 1a0 + for (i = 0; i + 1 < max;) { + 187: 89 de mov %ebx,%esi + 189: 83 c3 01 add $0x1,%ebx + 18c: 3b 5d 0c cmp 0xc(%ebp),%ebx + 18f: 7c cf jl 160 + break; + } + } + buf[i] = '\0'; + 191: 8b 45 08 mov 0x8(%ebp),%eax + 194: c6 04 30 00 movb $0x0,(%eax,%esi,1) + return buf; +} + 198: 8d 65 f4 lea -0xc(%ebp),%esp + 19b: 5b pop %ebx + 19c: 5e pop %esi + 19d: 5f pop %edi + 19e: 5d pop %ebp + 19f: c3 ret + buf[i] = '\0'; + 1a0: 8b 45 08 mov 0x8(%ebp),%eax + 1a3: 89 de mov %ebx,%esi + 1a5: c6 04 30 00 movb $0x0,(%eax,%esi,1) +} + 1a9: 8d 65 f4 lea -0xc(%ebp),%esp + 1ac: 5b pop %ebx + 1ad: 5e pop %esi + 1ae: 5f pop %edi + 1af: 5d pop %ebp + 1b0: c3 ret + 1b1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1b8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 1bf: 90 nop + +000001c0 : + +int stat(const char *n, struct stat *st) { + 1c0: 55 push %ebp + 1c1: 89 e5 mov %esp,%ebp + 1c3: 56 push %esi + 1c4: 53 push %ebx + int fd; + int r; + + fd = open(n, O_RDONLY); + 1c5: 83 ec 08 sub $0x8,%esp + 1c8: 6a 00 push $0x0 + 1ca: ff 75 08 push 0x8(%ebp) + 1cd: e8 19 01 00 00 call 2eb + if (fd < 0) { + 1d2: 83 c4 10 add $0x10,%esp + 1d5: 85 c0 test %eax,%eax + 1d7: 78 27 js 200 + return -1; + } + r = fstat(fd, st); + 1d9: 83 ec 08 sub $0x8,%esp + 1dc: ff 75 0c push 0xc(%ebp) + 1df: 89 c3 mov %eax,%ebx + 1e1: 50 push %eax + 1e2: e8 cc 00 00 00 call 2b3 + close(fd); + 1e7: 89 1c 24 mov %ebx,(%esp) + r = fstat(fd, st); + 1ea: 89 c6 mov %eax,%esi + close(fd); + 1ec: e8 2a 01 00 00 call 31b + return r; + 1f1: 83 c4 10 add $0x10,%esp +} + 1f4: 8d 65 f8 lea -0x8(%ebp),%esp + 1f7: 89 f0 mov %esi,%eax + 1f9: 5b pop %ebx + 1fa: 5e pop %esi + 1fb: 5d pop %ebp + 1fc: c3 ret + 1fd: 8d 76 00 lea 0x0(%esi),%esi + return -1; + 200: be ff ff ff ff mov $0xffffffff,%esi + 205: eb ed jmp 1f4 + 207: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 20e: 66 90 xchg %ax,%ax + +00000210 : + +int atoi(const char *s) { + 210: 55 push %ebp + 211: 89 e5 mov %esp,%ebp + 213: 53 push %ebx + 214: 8b 55 08 mov 0x8(%ebp),%edx + int n; + + n = 0; + while ('0' <= *s && *s <= '9') { + 217: 0f be 02 movsbl (%edx),%eax + 21a: 8d 48 d0 lea -0x30(%eax),%ecx + 21d: 80 f9 09 cmp $0x9,%cl + n = 0; + 220: b9 00 00 00 00 mov $0x0,%ecx + while ('0' <= *s && *s <= '9') { + 225: 77 1e ja 245 + 227: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 22e: 66 90 xchg %ax,%ax + n = n * 10 + *s++ - '0'; + 230: 83 c2 01 add $0x1,%edx + 233: 8d 0c 89 lea (%ecx,%ecx,4),%ecx + 236: 8d 4c 48 d0 lea -0x30(%eax,%ecx,2),%ecx + while ('0' <= *s && *s <= '9') { + 23a: 0f be 02 movsbl (%edx),%eax + 23d: 8d 58 d0 lea -0x30(%eax),%ebx + 240: 80 fb 09 cmp $0x9,%bl + 243: 76 eb jbe 230 + } + return n; +} + 245: 8b 5d fc mov -0x4(%ebp),%ebx + 248: 89 c8 mov %ecx,%eax + 24a: c9 leave + 24b: c3 ret + 24c: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + +00000250 : + +void* memmove(void *vdst, const void *vsrc, int n) { + 250: 55 push %ebp + 251: 89 e5 mov %esp,%ebp + 253: 57 push %edi + 254: 8b 45 10 mov 0x10(%ebp),%eax + 257: 8b 55 08 mov 0x8(%ebp),%edx + 25a: 56 push %esi + 25b: 8b 75 0c mov 0xc(%ebp),%esi + char *dst; + const char *src; + + dst = vdst; + src = vsrc; + while (n-- > 0) { + 25e: 85 c0 test %eax,%eax + 260: 7e 13 jle 275 + 262: 01 d0 add %edx,%eax + dst = vdst; + 264: 89 d7 mov %edx,%edi + 266: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 26d: 8d 76 00 lea 0x0(%esi),%esi + *dst++ = *src++; + 270: a4 movsb %ds:(%esi),%es:(%edi) + while (n-- > 0) { + 271: 39 f8 cmp %edi,%eax + 273: 75 fb jne 270 + } + return vdst; +} + 275: 5e pop %esi + 276: 89 d0 mov %edx,%eax + 278: 5f pop %edi + 279: 5d pop %ebp + 27a: c3 ret + +0000027b : +name: \ + movl $SYS_ ## name, %eax; \ + int $T_SYSCALL; \ + ret + +SYSCALL(fork) + 27b: b8 01 00 00 00 mov $0x1,%eax + 280: cd 40 int $0x40 + 282: c3 ret + +00000283 : +SYSCALL(exit) + 283: b8 02 00 00 00 mov $0x2,%eax + 288: cd 40 int $0x40 + 28a: c3 ret + +0000028b : +SYSCALL(wait) + 28b: b8 03 00 00 00 mov $0x3,%eax + 290: cd 40 int $0x40 + 292: c3 ret + +00000293 : +SYSCALL(pipe) + 293: b8 04 00 00 00 mov $0x4,%eax + 298: cd 40 int $0x40 + 29a: c3 ret + +0000029b : +SYSCALL(read) + 29b: b8 05 00 00 00 mov $0x5,%eax + 2a0: cd 40 int $0x40 + 2a2: c3 ret + +000002a3 : +SYSCALL(kill) + 2a3: b8 06 00 00 00 mov $0x6,%eax + 2a8: cd 40 int $0x40 + 2aa: c3 ret + +000002ab : +SYSCALL(exec) + 2ab: b8 07 00 00 00 mov $0x7,%eax + 2b0: cd 40 int $0x40 + 2b2: c3 ret + +000002b3 : +SYSCALL(fstat) + 2b3: b8 08 00 00 00 mov $0x8,%eax + 2b8: cd 40 int $0x40 + 2ba: c3 ret + +000002bb : +SYSCALL(chdir) + 2bb: b8 09 00 00 00 mov $0x9,%eax + 2c0: cd 40 int $0x40 + 2c2: c3 ret + +000002c3 : +SYSCALL(dup) + 2c3: b8 0a 00 00 00 mov $0xa,%eax + 2c8: cd 40 int $0x40 + 2ca: c3 ret + +000002cb : +SYSCALL(getpid) + 2cb: b8 0b 00 00 00 mov $0xb,%eax + 2d0: cd 40 int $0x40 + 2d2: c3 ret + +000002d3 : +SYSCALL(sbrk) + 2d3: b8 0c 00 00 00 mov $0xc,%eax + 2d8: cd 40 int $0x40 + 2da: c3 ret + +000002db : +SYSCALL(sleep) + 2db: b8 0d 00 00 00 mov $0xd,%eax + 2e0: cd 40 int $0x40 + 2e2: c3 ret + +000002e3 : +SYSCALL(uptime) + 2e3: b8 0e 00 00 00 mov $0xe,%eax + 2e8: cd 40 int $0x40 + 2ea: c3 ret + +000002eb : +SYSCALL(open) + 2eb: b8 0f 00 00 00 mov $0xf,%eax + 2f0: cd 40 int $0x40 + 2f2: c3 ret + +000002f3 : +SYSCALL(write) + 2f3: b8 10 00 00 00 mov $0x10,%eax + 2f8: cd 40 int $0x40 + 2fa: c3 ret + +000002fb : +SYSCALL(mknod) + 2fb: b8 11 00 00 00 mov $0x11,%eax + 300: cd 40 int $0x40 + 302: c3 ret + +00000303 : +SYSCALL(unlink) + 303: b8 12 00 00 00 mov $0x12,%eax + 308: cd 40 int $0x40 + 30a: c3 ret + +0000030b : +SYSCALL(link) + 30b: b8 13 00 00 00 mov $0x13,%eax + 310: cd 40 int $0x40 + 312: c3 ret + +00000313 : +SYSCALL(mkdir) + 313: b8 14 00 00 00 mov $0x14,%eax + 318: cd 40 int $0x40 + 31a: c3 ret + +0000031b : +SYSCALL(close) + 31b: b8 15 00 00 00 mov $0x15,%eax + 320: cd 40 int $0x40 + 322: c3 ret + +00000323 : +SYSCALL(getch) + 323: b8 16 00 00 00 mov $0x16,%eax + 328: cd 40 int $0x40 + 32a: c3 ret + +0000032b : +SYSCALL(greeting) + 32b: b8 17 00 00 00 mov $0x17,%eax + 330: cd 40 int $0x40 + 332: c3 ret + +00000333 : +SYSCALL(shutdown) + 333: b8 18 00 00 00 mov $0x18,%eax + 338: cd 40 int $0x40 + 33a: c3 ret + 33b: 66 90 xchg %ax,%ax + 33d: 66 90 xchg %ax,%ax + 33f: 90 nop + +00000340 : + +static void putc(int fd, char c) { + write(fd, &c, 1); +} + +static void printint(int fd, int xx, int base, int sgn) { + 340: 55 push %ebp + 341: 89 e5 mov %esp,%ebp + 343: 57 push %edi + 344: 56 push %esi + 345: 53 push %ebx + 346: 83 ec 3c sub $0x3c,%esp + 349: 89 4d c4 mov %ecx,-0x3c(%ebp) + uint x; + + neg = 0; + if (sgn && xx < 0) { + neg = 1; + x = -xx; + 34c: 89 d1 mov %edx,%ecx +static void printint(int fd, int xx, int base, int sgn) { + 34e: 89 45 b8 mov %eax,-0x48(%ebp) + if (sgn && xx < 0) { + 351: 85 d2 test %edx,%edx + 353: 0f 89 7f 00 00 00 jns 3d8 + 359: f6 45 08 01 testb $0x1,0x8(%ebp) + 35d: 74 79 je 3d8 + neg = 1; + 35f: c7 45 bc 01 00 00 00 movl $0x1,-0x44(%ebp) + x = -xx; + 366: f7 d9 neg %ecx + } + else { + x = xx; + } + + i = 0; + 368: 31 db xor %ebx,%ebx + 36a: 8d 75 d7 lea -0x29(%ebp),%esi + 36d: 8d 76 00 lea 0x0(%esi),%esi + do { + buf[i++] = digits[x % base]; + 370: 89 c8 mov %ecx,%eax + 372: 31 d2 xor %edx,%edx + 374: 89 cf mov %ecx,%edi + 376: f7 75 c4 divl -0x3c(%ebp) + 379: 0f b6 92 78 07 00 00 movzbl 0x778(%edx),%edx + 380: 89 45 c0 mov %eax,-0x40(%ebp) + 383: 89 d8 mov %ebx,%eax + 385: 8d 5b 01 lea 0x1(%ebx),%ebx + } + while ((x /= base) != 0); + 388: 8b 4d c0 mov -0x40(%ebp),%ecx + buf[i++] = digits[x % base]; + 38b: 88 14 1e mov %dl,(%esi,%ebx,1) + while ((x /= base) != 0); + 38e: 39 7d c4 cmp %edi,-0x3c(%ebp) + 391: 76 dd jbe 370 + if (neg) { + 393: 8b 4d bc mov -0x44(%ebp),%ecx + 396: 85 c9 test %ecx,%ecx + 398: 74 0c je 3a6 + buf[i++] = '-'; + 39a: c6 44 1d d8 2d movb $0x2d,-0x28(%ebp,%ebx,1) + buf[i++] = digits[x % base]; + 39f: 89 d8 mov %ebx,%eax + buf[i++] = '-'; + 3a1: ba 2d 00 00 00 mov $0x2d,%edx + } + + while (--i >= 0) { + 3a6: 8b 7d b8 mov -0x48(%ebp),%edi + 3a9: 8d 5c 05 d7 lea -0x29(%ebp,%eax,1),%ebx + 3ad: eb 07 jmp 3b6 + 3af: 90 nop + putc(fd, buf[i]); + 3b0: 0f b6 13 movzbl (%ebx),%edx + 3b3: 83 eb 01 sub $0x1,%ebx + write(fd, &c, 1); + 3b6: 83 ec 04 sub $0x4,%esp + 3b9: 88 55 d7 mov %dl,-0x29(%ebp) + 3bc: 6a 01 push $0x1 + 3be: 56 push %esi + 3bf: 57 push %edi + 3c0: e8 2e ff ff ff call 2f3 + while (--i >= 0) { + 3c5: 83 c4 10 add $0x10,%esp + 3c8: 39 de cmp %ebx,%esi + 3ca: 75 e4 jne 3b0 + } +} + 3cc: 8d 65 f4 lea -0xc(%ebp),%esp + 3cf: 5b pop %ebx + 3d0: 5e pop %esi + 3d1: 5f pop %edi + 3d2: 5d pop %ebp + 3d3: c3 ret + 3d4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + neg = 0; + 3d8: c7 45 bc 00 00 00 00 movl $0x0,-0x44(%ebp) + 3df: eb 87 jmp 368 + 3e1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3e8: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 3ef: 90 nop + +000003f0 : + +// Print to the given fd. Only understands %d, %x, %p, %s. +void printf(int fd, const char *fmt, ...) { + 3f0: 55 push %ebp + 3f1: 89 e5 mov %esp,%ebp + 3f3: 57 push %edi + 3f4: 56 push %esi + 3f5: 53 push %ebx + 3f6: 83 ec 2c sub $0x2c,%esp + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for (i = 0; fmt[i]; i++) { + 3f9: 8b 5d 0c mov 0xc(%ebp),%ebx +void printf(int fd, const char *fmt, ...) { + 3fc: 8b 75 08 mov 0x8(%ebp),%esi + for (i = 0; fmt[i]; i++) { + 3ff: 0f b6 13 movzbl (%ebx),%edx + 402: 84 d2 test %dl,%dl + 404: 74 6a je 470 + ap = (uint*)(void*)&fmt + 1; + 406: 8d 45 10 lea 0x10(%ebp),%eax + 409: 83 c3 01 add $0x1,%ebx + write(fd, &c, 1); + 40c: 8d 7d e7 lea -0x19(%ebp),%edi + state = 0; + 40f: 31 c9 xor %ecx,%ecx + ap = (uint*)(void*)&fmt + 1; + 411: 89 45 d0 mov %eax,-0x30(%ebp) + 414: eb 36 jmp 44c + 416: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 41d: 8d 76 00 lea 0x0(%esi),%esi + 420: 89 4d d4 mov %ecx,-0x2c(%ebp) + c = fmt[i] & 0xff; + if (state == 0) { + if (c == '%') { + state = '%'; + 423: b9 25 00 00 00 mov $0x25,%ecx + if (c == '%') { + 428: 83 f8 25 cmp $0x25,%eax + 42b: 74 15 je 442 + write(fd, &c, 1); + 42d: 83 ec 04 sub $0x4,%esp + 430: 88 55 e7 mov %dl,-0x19(%ebp) + 433: 6a 01 push $0x1 + 435: 57 push %edi + 436: 56 push %esi + 437: e8 b7 fe ff ff call 2f3 + 43c: 8b 4d d4 mov -0x2c(%ebp),%ecx + } + else { + putc(fd, c); + 43f: 83 c4 10 add $0x10,%esp + for (i = 0; fmt[i]; i++) { + 442: 0f b6 13 movzbl (%ebx),%edx + 445: 83 c3 01 add $0x1,%ebx + 448: 84 d2 test %dl,%dl + 44a: 74 24 je 470 + c = fmt[i] & 0xff; + 44c: 0f b6 c2 movzbl %dl,%eax + if (state == 0) { + 44f: 85 c9 test %ecx,%ecx + 451: 74 cd je 420 + } + } + else if (state == '%') { + 453: 83 f9 25 cmp $0x25,%ecx + 456: 75 ea jne 442 + if (c == 'd') { + 458: 83 f8 25 cmp $0x25,%eax + 45b: 0f 84 07 01 00 00 je 568 + 461: 83 e8 63 sub $0x63,%eax + 464: 83 f8 15 cmp $0x15,%eax + 467: 77 17 ja 480 + 469: ff 24 85 20 07 00 00 jmp *0x720(,%eax,4) + putc(fd, c); + } + state = 0; + } + } +} + 470: 8d 65 f4 lea -0xc(%ebp),%esp + 473: 5b pop %ebx + 474: 5e pop %esi + 475: 5f pop %edi + 476: 5d pop %ebp + 477: c3 ret + 478: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 47f: 90 nop + write(fd, &c, 1); + 480: 83 ec 04 sub $0x4,%esp + 483: 88 55 d4 mov %dl,-0x2c(%ebp) + 486: 6a 01 push $0x1 + 488: 57 push %edi + 489: 56 push %esi + 48a: c6 45 e7 25 movb $0x25,-0x19(%ebp) + 48e: e8 60 fe ff ff call 2f3 + putc(fd, c); + 493: 0f b6 55 d4 movzbl -0x2c(%ebp),%edx + write(fd, &c, 1); + 497: 83 c4 0c add $0xc,%esp + 49a: 88 55 e7 mov %dl,-0x19(%ebp) + 49d: 6a 01 push $0x1 + 49f: 57 push %edi + 4a0: 56 push %esi + 4a1: e8 4d fe ff ff call 2f3 + putc(fd, c); + 4a6: 83 c4 10 add $0x10,%esp + state = 0; + 4a9: 31 c9 xor %ecx,%ecx + 4ab: eb 95 jmp 442 + 4ad: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 16, 0); + 4b0: 83 ec 0c sub $0xc,%esp + 4b3: b9 10 00 00 00 mov $0x10,%ecx + 4b8: 6a 00 push $0x0 + 4ba: 8b 45 d0 mov -0x30(%ebp),%eax + 4bd: 8b 10 mov (%eax),%edx + 4bf: 89 f0 mov %esi,%eax + 4c1: e8 7a fe ff ff call 340 + ap++; + 4c6: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 4ca: 83 c4 10 add $0x10,%esp + state = 0; + 4cd: 31 c9 xor %ecx,%ecx + 4cf: e9 6e ff ff ff jmp 442 + 4d4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + s = (char*)*ap; + 4d8: 8b 45 d0 mov -0x30(%ebp),%eax + 4db: 8b 10 mov (%eax),%edx + ap++; + 4dd: 83 c0 04 add $0x4,%eax + 4e0: 89 45 d0 mov %eax,-0x30(%ebp) + if (s == 0) { + 4e3: 85 d2 test %edx,%edx + 4e5: 0f 84 8d 00 00 00 je 578 + while (*s != 0) { + 4eb: 0f b6 02 movzbl (%edx),%eax + state = 0; + 4ee: 31 c9 xor %ecx,%ecx + while (*s != 0) { + 4f0: 84 c0 test %al,%al + 4f2: 0f 84 4a ff ff ff je 442 + 4f8: 89 5d d4 mov %ebx,-0x2c(%ebp) + 4fb: 89 d3 mov %edx,%ebx + 4fd: 8d 76 00 lea 0x0(%esi),%esi + write(fd, &c, 1); + 500: 83 ec 04 sub $0x4,%esp + s++; + 503: 83 c3 01 add $0x1,%ebx + 506: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 509: 6a 01 push $0x1 + 50b: 57 push %edi + 50c: 56 push %esi + 50d: e8 e1 fd ff ff call 2f3 + while (*s != 0) { + 512: 0f b6 03 movzbl (%ebx),%eax + 515: 83 c4 10 add $0x10,%esp + 518: 84 c0 test %al,%al + 51a: 75 e4 jne 500 + state = 0; + 51c: 8b 5d d4 mov -0x2c(%ebp),%ebx + 51f: 31 c9 xor %ecx,%ecx + 521: e9 1c ff ff ff jmp 442 + 526: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 52d: 8d 76 00 lea 0x0(%esi),%esi + printint(fd, *ap, 10, 1); + 530: 83 ec 0c sub $0xc,%esp + 533: b9 0a 00 00 00 mov $0xa,%ecx + 538: 6a 01 push $0x1 + 53a: e9 7b ff ff ff jmp 4ba + 53f: 90 nop + putc(fd, *ap); + 540: 8b 45 d0 mov -0x30(%ebp),%eax + write(fd, &c, 1); + 543: 83 ec 04 sub $0x4,%esp + putc(fd, *ap); + 546: 8b 00 mov (%eax),%eax + write(fd, &c, 1); + 548: 6a 01 push $0x1 + 54a: 57 push %edi + 54b: 56 push %esi + putc(fd, *ap); + 54c: 88 45 e7 mov %al,-0x19(%ebp) + write(fd, &c, 1); + 54f: e8 9f fd ff ff call 2f3 + ap++; + 554: 83 45 d0 04 addl $0x4,-0x30(%ebp) + 558: 83 c4 10 add $0x10,%esp + state = 0; + 55b: 31 c9 xor %ecx,%ecx + 55d: e9 e0 fe ff ff jmp 442 + 562: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + putc(fd, c); + 568: 88 55 e7 mov %dl,-0x19(%ebp) + write(fd, &c, 1); + 56b: 83 ec 04 sub $0x4,%esp + 56e: e9 2a ff ff ff jmp 49d + 573: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + 577: 90 nop + s = "(null)"; + 578: ba 18 07 00 00 mov $0x718,%edx + while (*s != 0) { + 57d: 89 5d d4 mov %ebx,-0x2c(%ebp) + 580: b8 28 00 00 00 mov $0x28,%eax + 585: 89 d3 mov %edx,%ebx + 587: e9 74 ff ff ff jmp 500 + 58c: 66 90 xchg %ax,%ax + 58e: 66 90 xchg %ax,%ax + +00000590 : +typedef union header Header; + +static Header base; +static Header *freep; + +void free(void *ap) { + 590: 55 push %ebp + Header *bp, *p; + + bp = (Header*)ap - 1; + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 591: a1 20 0a 00 00 mov 0xa20,%eax +void free(void *ap) { + 596: 89 e5 mov %esp,%ebp + 598: 57 push %edi + 599: 56 push %esi + 59a: 53 push %ebx + 59b: 8b 5d 08 mov 0x8(%ebp),%ebx + bp = (Header*)ap - 1; + 59e: 8d 4b f8 lea -0x8(%ebx),%ecx + for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) { + 5a1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi + 5a8: 89 c2 mov %eax,%edx + 5aa: 8b 00 mov (%eax),%eax + 5ac: 39 ca cmp %ecx,%edx + 5ae: 73 30 jae 5e0 + 5b0: 39 c1 cmp %eax,%ecx + 5b2: 72 04 jb 5b8 + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 5b4: 39 c2 cmp %eax,%edx + 5b6: 72 f0 jb 5a8 + break; + } + } + if (bp + bp->s.size == p->s.ptr) { + 5b8: 8b 73 fc mov -0x4(%ebx),%esi + 5bb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 5be: 39 f8 cmp %edi,%eax + 5c0: 74 30 je 5f2 + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + 5c2: 89 43 f8 mov %eax,-0x8(%ebx) + } + else { + bp->s.ptr = p->s.ptr; + } + if (p + p->s.size == bp) { + 5c5: 8b 42 04 mov 0x4(%edx),%eax + 5c8: 8d 34 c2 lea (%edx,%eax,8),%esi + 5cb: 39 f1 cmp %esi,%ecx + 5cd: 74 3a je 609 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + 5cf: 89 0a mov %ecx,(%edx) + } + else { + p->s.ptr = bp; + } + freep = p; +} + 5d1: 5b pop %ebx + freep = p; + 5d2: 89 15 20 0a 00 00 mov %edx,0xa20 +} + 5d8: 5e pop %esi + 5d9: 5f pop %edi + 5da: 5d pop %ebp + 5db: c3 ret + 5dc: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi + if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) { + 5e0: 39 c2 cmp %eax,%edx + 5e2: 72 c4 jb 5a8 + 5e4: 39 c1 cmp %eax,%ecx + 5e6: 73 c0 jae 5a8 + if (bp + bp->s.size == p->s.ptr) { + 5e8: 8b 73 fc mov -0x4(%ebx),%esi + 5eb: 8d 3c f1 lea (%ecx,%esi,8),%edi + 5ee: 39 f8 cmp %edi,%eax + 5f0: 75 d0 jne 5c2 + bp->s.size += p->s.ptr->s.size; + 5f2: 03 70 04 add 0x4(%eax),%esi + 5f5: 89 73 fc mov %esi,-0x4(%ebx) + bp->s.ptr = p->s.ptr->s.ptr; + 5f8: 8b 02 mov (%edx),%eax + 5fa: 8b 00 mov (%eax),%eax + 5fc: 89 43 f8 mov %eax,-0x8(%ebx) + if (p + p->s.size == bp) { + 5ff: 8b 42 04 mov 0x4(%edx),%eax + 602: 8d 34 c2 lea (%edx,%eax,8),%esi + 605: 39 f1 cmp %esi,%ecx + 607: 75 c6 jne 5cf + p->s.size += bp->s.size; + 609: 03 43 fc add -0x4(%ebx),%eax + freep = p; + 60c: 89 15 20 0a 00 00 mov %edx,0xa20 + p->s.size += bp->s.size; + 612: 89 42 04 mov %eax,0x4(%edx) + p->s.ptr = bp->s.ptr; + 615: 8b 4b f8 mov -0x8(%ebx),%ecx + 618: 89 0a mov %ecx,(%edx) +} + 61a: 5b pop %ebx + 61b: 5e pop %esi + 61c: 5f pop %edi + 61d: 5d pop %ebp + 61e: c3 ret + 61f: 90 nop + +00000620 : + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* malloc(uint nbytes) { + 620: 55 push %ebp + 621: 89 e5 mov %esp,%ebp + 623: 57 push %edi + 624: 56 push %esi + 625: 53 push %ebx + 626: 83 ec 1c sub $0x1c,%esp + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 629: 8b 45 08 mov 0x8(%ebp),%eax + if ((prevp = freep) == 0) { + 62c: 8b 3d 20 0a 00 00 mov 0xa20,%edi + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + 632: 8d 70 07 lea 0x7(%eax),%esi + 635: c1 ee 03 shr $0x3,%esi + 638: 83 c6 01 add $0x1,%esi + if ((prevp = freep) == 0) { + 63b: 85 ff test %edi,%edi + 63d: 0f 84 9d 00 00 00 je 6e0 + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 643: 8b 17 mov (%edi),%edx + if (p->s.size >= nunits) { + 645: 8b 4a 04 mov 0x4(%edx),%ecx + 648: 39 f1 cmp %esi,%ecx + 64a: 73 6a jae 6b6 + 64c: bb 00 10 00 00 mov $0x1000,%ebx + 651: 39 de cmp %ebx,%esi + 653: 0f 43 de cmovae %esi,%ebx + p = sbrk(nu * sizeof(Header)); + 656: 8d 04 dd 00 00 00 00 lea 0x0(,%ebx,8),%eax + 65d: 89 45 e4 mov %eax,-0x1c(%ebp) + 660: eb 17 jmp 679 + 662: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 668: 8b 02 mov (%edx),%eax + if (p->s.size >= nunits) { + 66a: 8b 48 04 mov 0x4(%eax),%ecx + 66d: 39 f1 cmp %esi,%ecx + 66f: 73 4f jae 6c0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if (p == freep) { + 671: 8b 3d 20 0a 00 00 mov 0xa20,%edi + 677: 89 c2 mov %eax,%edx + 679: 39 d7 cmp %edx,%edi + 67b: 75 eb jne 668 + p = sbrk(nu * sizeof(Header)); + 67d: 83 ec 0c sub $0xc,%esp + 680: ff 75 e4 push -0x1c(%ebp) + 683: e8 4b fc ff ff call 2d3 + if (p == (char*)-1) { + 688: 83 c4 10 add $0x10,%esp + 68b: 83 f8 ff cmp $0xffffffff,%eax + 68e: 74 1c je 6ac + hp->s.size = nu; + 690: 89 58 04 mov %ebx,0x4(%eax) + free((void*)(hp + 1)); + 693: 83 ec 0c sub $0xc,%esp + 696: 83 c0 08 add $0x8,%eax + 699: 50 push %eax + 69a: e8 f1 fe ff ff call 590 + return freep; + 69f: 8b 15 20 0a 00 00 mov 0xa20,%edx + if ((p = morecore(nunits)) == 0) { + 6a5: 83 c4 10 add $0x10,%esp + 6a8: 85 d2 test %edx,%edx + 6aa: 75 bc jne 668 + return 0; + } + } + } +} + 6ac: 8d 65 f4 lea -0xc(%ebp),%esp + return 0; + 6af: 31 c0 xor %eax,%eax +} + 6b1: 5b pop %ebx + 6b2: 5e pop %esi + 6b3: 5f pop %edi + 6b4: 5d pop %ebp + 6b5: c3 ret + if (p->s.size >= nunits) { + 6b6: 89 d0 mov %edx,%eax + 6b8: 89 fa mov %edi,%edx + 6ba: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + if (p->s.size == nunits) { + 6c0: 39 ce cmp %ecx,%esi + 6c2: 74 4c je 710 + p->s.size -= nunits; + 6c4: 29 f1 sub %esi,%ecx + 6c6: 89 48 04 mov %ecx,0x4(%eax) + p += p->s.size; + 6c9: 8d 04 c8 lea (%eax,%ecx,8),%eax + p->s.size = nunits; + 6cc: 89 70 04 mov %esi,0x4(%eax) + freep = prevp; + 6cf: 89 15 20 0a 00 00 mov %edx,0xa20 +} + 6d5: 8d 65 f4 lea -0xc(%ebp),%esp + return (void*)(p + 1); + 6d8: 83 c0 08 add $0x8,%eax +} + 6db: 5b pop %ebx + 6dc: 5e pop %esi + 6dd: 5f pop %edi + 6de: 5d pop %ebp + 6df: c3 ret + base.s.ptr = freep = prevp = &base; + 6e0: c7 05 20 0a 00 00 24 movl $0xa24,0xa20 + 6e7: 0a 00 00 + base.s.size = 0; + 6ea: bf 24 0a 00 00 mov $0xa24,%edi + base.s.ptr = freep = prevp = &base; + 6ef: c7 05 24 0a 00 00 24 movl $0xa24,0xa24 + 6f6: 0a 00 00 + for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) { + 6f9: 89 fa mov %edi,%edx + base.s.size = 0; + 6fb: c7 05 28 0a 00 00 00 movl $0x0,0xa28 + 702: 00 00 00 + if (p->s.size >= nunits) { + 705: e9 42 ff ff ff jmp 64c + 70a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi + prevp->s.ptr = p->s.ptr; + 710: 8b 08 mov (%eax),%ecx + 712: 89 0a mov %ecx,(%edx) + 714: eb b9 jmp 6cf diff --git a/zombie.c b/zombie.c new file mode 100644 index 0000000..144c349 --- /dev/null +++ b/zombie.c @@ -0,0 +1,13 @@ +// Create a zombie process that +// must be reparented at exit. + +#include "types.h" +#include "stat.h" +#include "user.h" + +int main(void) { + if (fork() > 0) { + sleep(5); // Let child exit before parent. + } + exit(); +} diff --git a/zombie.d b/zombie.d new file mode 100644 index 0000000..c3e36f5 --- /dev/null +++ b/zombie.d @@ -0,0 +1 @@ +zombie.o: zombie.c /usr/include/stdc-predef.h types.h stat.h user.h diff --git a/zombie.o b/zombie.o new file mode 100644 index 0000000..db656c2 Binary files /dev/null and b/zombie.o differ diff --git a/zombie.sym b/zombie.sym new file mode 100644 index 0000000..55f4a43 --- /dev/null +++ b/zombie.sym @@ -0,0 +1,48 @@ +00000000 zombie.c +00000000 ulib.c +00000000 printf.c +00000340 printint +00000778 digits.0 +00000000 umalloc.c +00000a20 freep +00000a24 base +00000030 strcpy +000003f0 printf +0000032b greeting +00000250 memmove +000002fb mknod +00000150 gets +000002cb getpid +00000620 malloc +000002db sleep +00000293 pipe +00000323 getch +000002f3 write +000002b3 fstat +000002a3 kill +000002bb chdir +000002ab exec +0000028b wait +0000029b read +00000303 unlink +0000027b fork +000002d3 sbrk +000002e3 uptime +00000a20 __bss_start +000000f0 memset +00000000 main +00000060 strcmp +00000333 shutdown +000002c3 dup +000001c0 stat +00000a20 _edata +00000a2c _end +0000030b link +00000283 exit +00000210 atoi +000000c0 strlen +000002eb open +00000110 strchr +00000313 mkdir +0000031b close +00000590 free