From f53494c28e362fb7752bbc83417b9ba47cff0bf5 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 3 Sep 2008 04:50:04 +0000 Subject: DO NOT MAIL: xv6 web pages --- web/l2.html | 494 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 494 insertions(+) create mode 100644 web/l2.html (limited to 'web/l2.html') diff --git a/web/l2.html b/web/l2.html new file mode 100644 index 0000000..e183d5a --- /dev/null +++ b/web/l2.html @@ -0,0 +1,494 @@ + +
+
+for(;;){
+ run next instruction
+}
+
+
+
+#define DATA_PORT 0x378
+#define STATUS_PORT 0x379
+#define BUSY 0x80
+#define CONTROL_PORT 0x37A
+#define STROBE 0x01
+void
+lpt_putc(int c)
+{
+ /* wait for printer to consume previous byte */
+ while((inb(STATUS_PORT) & BUSY) == 0)
+ ;
+
+ /* put the byte on the parallel lines */
+ outb(DATA_PORT, c);
+
+ /* tell the printer to look at the data */
+ outb(CONTROL_PORT, STROBE);
+ outb(CONTROL_PORT, 0);
+}
+
+
++------------------+ <- 0xFFFFFFFF (4GB) +| 32-bit | +| memory mapped | +| devices | +| | +/\/\/\/\/\/\/\/\/\/\ + +/\/\/\/\/\/\/\/\/\/\ +| | +| Unused | +| | ++------------------+ <- depends on amount of RAM +| | +| | +| Extended Memory | +| | +| | ++------------------+ <- 0x00100000 (1MB) +| BIOS ROM | ++------------------+ <- 0x000F0000 (960KB) +| 16-bit devices, | +| expansion ROMs | ++------------------+ <- 0x000C0000 (768KB) +| VGA Display | ++------------------+ <- 0x000A0000 (640KB) +| | +| Low Memory | +| | ++------------------+ <- 0x00000000 ++ +
| AT&T syntax | "C"-ish equivalent + | |
| movl %eax, %edx | edx = eax; | register mode + |
| movl $0x123, %edx | edx = 0x123; | immediate + |
| movl 0x123, %edx | edx = *(int32_t*)0x123; | direct + |
| movl (%ebx), %edx | edx = *(int32_t*)ebx; | indirect + |
| movl 4(%ebx), %edx | edx = *(int32_t*)(ebx+4); | displaced + |
| Example instruction | What it does + |
| pushl %eax + |
+ subl $4, %esp + movl %eax, (%esp) + |
| popl %eax + |
+ movl (%esp), %eax + addl $4, %esp + |
| call $0x12345 + |
+ pushl %eip (*) + movl $0x12345, %eip (*) + |
| ret + | + popl %eip (*) + |
+ +------------+ | + | arg 2 | \ + +------------+ >- previous function's stack frame + | arg 1 | / + +------------+ | + | ret %eip | / + +============+ + | saved %ebp | \ + %ebp-> +------------+ | + | | | + | local | \ + | variables, | >- current function's stack frame + | etc. | / + | | | + | | | + %esp-> +------------+ / ++
+ pushl %ebp + movl %esp, %ebp ++
+ movl %ebp, %esp + popl %ebp ++ or +
+ leave ++
+ int main(void) { return f(8)+1; }
+ int f(int x) { return g(x); }
+ int g(int x) { return x+3; }
+
+ + _main: + prologue + pushl %ebp + movl %esp, %ebp + body + pushl $8 + call _f + addl $1, %eax + epilogue + movl %ebp, %esp + popl %ebp + ret + _f: + prologue + pushl %ebp + movl %esp, %ebp + body + pushl 8(%esp) + call _g + epilogue + movl %ebp, %esp + popl %ebp + ret + + _g: + prologue + pushl %ebp + movl %esp, %ebp + save %ebx + pushl %ebx + body + movl 8(%ebp), %ebx + addl $3, %ebx + movl %ebx, %eax + restore %ebx + popl %ebx + epilogue + movl %ebp, %esp + popl %ebp + ret ++
+ _g: + movl 4(%esp), %eax + addl $3, %eax + ret ++ +
+ int32_t regs[8]; + #define REG_EAX 1; + #define REG_EBX 2; + #define REG_ECX 3; + ... + int32_t eip; + int16_t segregs[4]; + ... ++
+ for (;;) {
+ read_instruction();
+ switch (decode_instruction_opcode()) {
+ case OPCODE_ADD:
+ int src = decode_src_reg();
+ int dst = decode_dst_reg();
+ regs[dst] = regs[dst] + regs[src];
+ break;
+ case OPCODE_SUB:
+ int src = decode_src_reg();
+ int dst = decode_dst_reg();
+ regs[dst] = regs[dst] - regs[src];
+ break;
+ ...
+ }
+ eip += instruction_length;
+ }
+
+
+
+ #define KB 1024
+ #define MB 1024*1024
+
+ #define LOW_MEMORY 640*KB
+ #define EXT_MEMORY 10*MB
+
+ uint8_t low_mem[LOW_MEMORY];
+ uint8_t ext_mem[EXT_MEMORY];
+ uint8_t bios_rom[64*KB];
+
+ uint8_t read_byte(uint32_t phys_addr) {
+ if (phys_addr < LOW_MEMORY)
+ return low_mem[phys_addr];
+ else if (phys_addr >= 960*KB && phys_addr < 1*MB)
+ return rom_bios[phys_addr - 960*KB];
+ else if (phys_addr >= 1*MB && phys_addr < 1*MB+EXT_MEMORY) {
+ return ext_mem[phys_addr-1*MB];
+ else ...
+ }
+
+ void write_byte(uint32_t phys_addr, uint8_t val) {
+ if (phys_addr < LOW_MEMORY)
+ low_mem[phys_addr] = val;
+ else if (phys_addr >= 960*KB && phys_addr < 1*MB)
+ ; /* ignore attempted write to ROM! */
+ else if (phys_addr >= 1*MB && phys_addr < 1*MB+EXT_MEMORY) {
+ ext_mem[phys_addr-1*MB] = val;
+ else ...
+ }
+
+