Files
sanbuphy f44c842fe7 feat(docs): update computer fundamentals content and demos
- Refactor frontend framework demo descriptions for clarity
- Remove interactive features from triad and field map demos
- Add new computer organization and DSL documentation links
- Split type systems and compilers into separate pages
- Enhance power-on-to-web article with relay race analogy
- Add new interactive demos for type systems and compilation
- Improve visual presentation of boot process and hardware flow
- Introduce new Vibe Coding flow demo component
2026-02-25 01:38:27 +08:00

399 lines
9.2 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="instruction-format-demo">
<div class="demo-header">
<span class="title">机器指令格式</span>
<span class="subtitle">操作码 + 操作数 = 机器指令</span>
</div>
<div class="format-selector">
<button
v-for="fmt in instructionFormats"
:key="fmt.type"
:class="['format-btn', { active: selectedFormat === fmt.type }]"
@click="selectedFormat = fmt.type"
>
{{ fmt.type }}
</button>
</div>
<div class="format-visualization" v-if="selectedFormatData">
<div class="format-diagram">
<div
v-for="(field, i) in selectedFormatData.fields"
:key="i"
class="field-box"
:style="{ flex: field.bits }"
>
<span class="field-name">{{ field.name }}</span>
<span class="field-bits">{{ field.bits }}</span>
</div>
</div>
<div class="format-example">
<div class="example-title">示例指令</div>
<div class="binary-display">
<span
v-for="(bit, i) in selectedFormatData.example"
:key="i"
class="bit"
:class="{ highlight: isHighlight(i, selectedFormatData) }"
>
{{ bit }}
</span>
</div>
<div class="example-desc">{{ selectedFormatData.description }}</div>
</div>
<div class="format-explanation">
<div class="exp-title">{{ selectedFormatData.type }} 格式说明</div>
<div class="exp-content">{{ selectedFormatData.explanation }}</div>
<div class="examples-list" v-if="selectedFormatData.examples">
<div class="list-title">常见指令示例</div>
<div v-for="ex in selectedFormatData.examples" :key="ex.name" class="example-item">
<span class="ex-name">{{ ex.name }}</span>
<span class="ex-desc">{{ ex.desc }}</span>
</div>
</div>
</div>
</div>
<div class="opcode-table">
<div class="table-title">常用操作码 (Opcode)</div>
<div class="opcode-grid">
<div v-for="op in opcodes" :key="op.code" class="opcode-item">
<span class="op-code">{{ op.code }}</span>
<span class="op-name">{{ op.name }}</span>
<span class="op-desc">{{ op.desc }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const selectedFormat = ref('three-address')
const instructionFormats = ref([
{
type: '零地址',
fields: [{ name: '操作码', bits: 8 }],
example: '01101100',
description: '操作数隐含在栈顶',
explanation: '零地址指令只有操作码,操作数隐含在操作数栈中。常用于堆栈计算机,如 ENTER、EXIT 等。',
examples: [
{ name: 'POP', desc: '弹出栈顶数据' },
{ name: 'PUSH', desc: '压入数据到栈顶' },
{ name: 'CALL', desc: '调用子程序' }
]
},
{
type: '一地址',
fields: [
{ name: '操作码', bits: 8 },
{ name: '地址', bits: 24 }
],
example: '01101100 00000001 00000010 00000011',
description: '一个操作数地址,另一个隐含',
explanation: '一地址指令有一个操作数在内存/寄存器中,另一个操作数隐含在 ACC(累加器)中。如 INC、DEC 等单操作数指令。',
examples: [
{ name: 'INC A', desc: 'A = A + 1' },
{ name: 'DEC A', desc: 'A = A - 1' },
{ name: 'NOT A', desc: 'A = ~A' }
]
},
{
type: '二地址',
fields: [
{ name: '操作码', bits: 8 },
{ name: '目的地址', bits: 8 },
{ name: '源地址', bits: 8 }
],
example: '01101100 00000001 00000010',
description: '两个操作数地址,结果存目的地址',
explanation: '最常用的指令格式。两个操作数地址,结果覆盖目的操作数。如 ADD、SUB、MOV 等。',
examples: [
{ name: 'MOV R1, R2', desc: 'R1 = R2' },
{ name: 'ADD R1, R2', desc: 'R1 = R1 + R2' },
{ name: 'SUB R1, R2', desc: 'R1 = R1 - R2' }
]
},
{
type: '三地址',
fields: [
{ name: '操作码', bits: 8 },
{ name: '目的', bits: 8 },
{ name: '源1', bits: 8 },
{ name: '源2', bits: 8 }
],
example: '01101100 00000001 00000010 00000011',
description: '结果存新地址,不破坏源操作数',
explanation: '三个地址分别指定目的操作数和两个源操作数。结果存入目的地址,不改变源操作数。常见于复杂指令集。',
examples: [
{ name: 'ADD R1, R2, R3', desc: 'R1 = R2 + R3' },
{ name: 'SUB R1, R2, R3', desc: 'R1 = R2 - R3' },
{ name: 'MUL R1, R2, R3', desc: 'R1 = R2 × R3' }
]
}
])
const selectedFormatData = computed(() => {
return instructionFormats.value.find(f => f.type === selectedFormat.value)
})
const isHighlight = (index, formatData) => {
const opcodeBits = 8
return index < opcodeBits
}
const opcodes = ref([
{ code: '00000000', name: 'NOP', desc: '无操作' },
{ code: '00000001', name: 'MOV', desc: '数据传送' },
{ code: '00000010', name: 'ADD', desc: '加法' },
{ code: '00000011', name: 'SUB', desc: '减法' },
{ code: '00000100', name: 'MUL', desc: '乘法' },
{ code: '00000101', name: 'DIV', desc: '除法' },
{ code: '00000110', name: 'AND', desc: '逻辑与' },
{ code: '00000111', name: 'OR', desc: '逻辑或' },
{ code: '00001000', name: 'NOT', desc: '逻辑非' },
{ code: '00001001', name: 'XOR', desc: '异或' },
{ code: '00001010', name: 'SHL', desc: '左移' },
{ code: '00001011', name: 'SHR', desc: '右移' },
{ code: '00001100', name: 'JMP', desc: '无条件跳转' },
{ code: '00001101', name: 'JE', desc: '相等跳转' },
{ code: '00001110', name: 'JNE', desc: '不等跳转' },
{ code: '00001111', name: 'CALL', desc: '调用子程序' },
{ code: '00010000', name: 'RET', desc: '返回' },
{ code: '00010001', name: 'PUSH', desc: '压栈' },
{ code: '00010010', name: 'POP', desc: '出栈' },
{ code: '00010011', name: 'LOAD', desc: '从内存加载' },
{ code: '00010100', name: 'STORE', desc: '存入内存' }
])
</script>
<style scoped>
.instruction-format-demo {
background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
border-radius: 12px;
padding: 20px;
margin: 16px 0;
}
.demo-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.title {
font-size: 18px;
font-weight: 700;
color: #1e293b;
}
.subtitle {
font-size: 13px;
color: #64748b;
margin-left: auto;
}
.format-selector {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
.format-btn {
padding: 8px 16px;
border: 2px solid #e2e8f0;
border-radius: 6px;
background: white;
cursor: pointer;
font-size: 13px;
font-weight: 500;
transition: all 0.2s;
}
.format-btn.active {
border-color: #22c55e;
background: #dcfce7;
color: #166534;
}
.format-visualization {
background: white;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
}
.format-diagram {
display: flex;
gap: 2px;
margin-bottom: 16px;
}
.field-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 12px 8px;
background: #e0f2fe;
border-radius: 4px;
text-align: center;
}
.field-box:first-child {
background: #fef3c7;
}
.field-name {
font-size: 12px;
font-weight: 600;
color: #1e293b;
}
.field-bits {
font-size: 10px;
color: #64748b;
}
.format-example {
padding: 12px;
background: #f8fafc;
border-radius: 6px;
margin-bottom: 12px;
}
.example-title {
font-size: 12px;
font-weight: 600;
color: #1e293b;
margin-bottom: 8px;
}
.binary-display {
display: flex;
flex-wrap: wrap;
gap: 2px;
margin-bottom: 8px;
}
.bit {
padding: 4px 6px;
background: #e2e8f0;
border-radius: 2px;
font-family: monospace;
font-size: 12px;
color: #475569;
}
.bit.highlight {
background: #fef3c7;
font-weight: 600;
}
.example-desc {
font-size: 11px;
color: #64748b;
}
.format-explanation {
padding: 12px;
background: #f0f9ff;
border-radius: 6px;
}
.exp-title {
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin-bottom: 8px;
}
.exp-content {
font-size: 12px;
color: #475569;
line-height: 1.6;
}
.examples-list {
margin-top: 12px;
}
.list-title {
font-size: 12px;
font-weight: 600;
color: #1e293b;
margin-bottom: 6px;
}
.example-item {
display: flex;
gap: 12px;
padding: 4px 0;
font-size: 11px;
}
.ex-name {
font-family: monospace;
color: #0369a1;
min-width: 80px;
}
.ex-desc {
color: #64748b;
}
.opcode-table {
background: white;
border-radius: 8px;
padding: 12px;
}
.table-title {
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin-bottom: 12px;
}
.opcode-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 8px;
}
.opcode-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
background: #f8fafc;
border-radius: 4px;
font-size: 11px;
}
.op-code {
font-family: monospace;
padding: 2px 6px;
background: #e0f2fe;
border-radius: 2px;
color: #0369a1;
}
.op-name {
font-weight: 600;
color: #1e293b;
min-width: 40px;
}
.op-desc {
color: #64748b;
}
</style>