⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdos.asm

📁 FDOS Operating System
💻 ASM
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Project 		: 	FDOS 0.0.7
;; Author 		: 	Stefan Tappertzhofen (tappertzhofen@t-online.de)
;; Webpage 		: 	http://www.visual-opal.de
;; Date 		: 	17. September 2003
;; Info		 	: 	Loader, Kernel, Shell
;; Filename 		: 	fdos.asm
;; Compile Syntax 	: 	nasm fdos.asm -f bin -o fdos.sys
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Macro Variablen
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Inititialisierung
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Init:
	MOV AX, CS			; Segment Register vorbereiten
        MOV DS, AX
        MOV ES, AX


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Start
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


	CMP BX, 1			; BX = 1 (wenn kein kompletter neustart)
	JE NEAR Begin			; Sprung zum Hauptprogramm

	MOV SI, MSG_Welcome		; Pointer zum String
	CALL WriteString		; Prozedur Sringausgabe

	MOV SI, MSG_LoadKernel		; Pointer zum String
	CALL WriteString		; Prozedur Stringausgabe

	CALL Point			; Punkt ausgaben

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Int 21 Initialisieren
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	SHL EAX, 16			; EAX um 16 Bit nach links verschieben
	MOV AX, int21h			; AX verweist auf den Code des neuen Interrupts
	XOR BX, BX			; BX = 0
	MOV FS, BX			; FS = 0

	CALL Point			; Schreibe Zeichen

	CLI				; Interrupt Flag l鰏chen
	MOV [FS:21h*4], EAX		; Interrupt in Int. Tabelle speichern
	STI				; Interrupt Flag setzten

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; FDOS Multi Kernel Initialisierung
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	PUSH ES
	PUSH DS

		MOV AX, 6620h
		MOV ES, AX
		MOV DS, AX

		XOR AX, AX

		MOV DI, AX

		STOSW
		STOSW


	POP DS
	POP ES

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Prozess Tabelle initialisieren
;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	MOV AH, 26			; Tabelle leeren
	INT 21h

	MOV BX, 1			; Kernel
	MOV DX, 50h
	MOV DI, 1F60h
	MOV AH, 24
	INT 21h

	MOV BX, 2			; FAT
	MOV DX, 2000h
	MOV DI, 2400h
	MOV AH, 24
	INT 21h

	MOV BX, 3			; Verzeichnis
	MOV DX, 4401h
	MOV DI, 1FFFh
	MOV AH, 24
	INT 21h

	MOV BX, 4			; Verzeichnis Name
	MOV DX, 6400h
	MOV DI, 100h
	MOV AH, 24
	INT 21h

	MOV BX, 5			; Tastatur Codes
	MOV DX, 6500h
	MOV DI, 100h
	MOV AH, 24
	INT 21h

	MOV BX, 6			; Kernel Variables
	MOV DX, 6601h
	MOV DI, 25
	MOV AH, 24
	INT 21h

	MOV BX, 7			; Reserviert
	MOV DX, 6620h
	MOV DI, 79h
	MOV AH, 24
	INT 21h

	MOV BX, 8			; Shell Variablen
	MOV DX, 6700h
	MOV DI, 100h
	MOV AH, 24
	INT 21h

	MOV BX, 7			; Reserviert
	MOV DX, 6801h
	MOV DI, 8FFh
	MOV AH, 24
	INT 21h

	MOV BX, 10			; Prozesse
	MOV DX, 7100h
	MOV DI, 100h
	MOV AH, 24
	INT 21h

	MOV BX, 9			; FDOS Verzeichnis
	MOV DX, 7200h
	MOV DI, 3584
	MOV AH, 24
	INT 21h


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Startverzeichnis einlesen
;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	MOV AX, 50h			; DS und ES Register vorbereiten
	MOV ES, AX
	MOV DS, AX

	MOV AH, 18			; Root Dir einlesen
	MOV BX, 4401h			; Offset
	INT 21h				; Ausf黨ren


	;; BX = 6400h = Name des aktuellen Verzeichnisses

	MOV SI, RootDirName		; Speichere den Namen des
	MOV BX, 6400h			; aktuellen Verzeichnisses
	MOV DI, BX			; in den Arbeitsspeicher
	
	Boot_SaveRootName:

		LODSB			; [SI] > AL; SI + 1
		STOSB			; AL > [DI]; DI + 1
		CMP AL, 0		; Wenn AL nicht 0 ist, dann weiterlaufen
		JNE SHORT Boot_SaveRootName


	MOV DI, Path			; Hauptpfad initialisieren
	MOV AL, 'A'
	STOSB				; AL nach DI schreiben
	MOV AL, ':'
	STOSB				; AL nach DI schreiben
	MOV AL, 0
	STOSB				; AL nach DI schreiben


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Tastaturscancodes vorlanden
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	PUSH DS				; DS zwischenspeichern

		MOV EAX, 50h		; Segment 50h
		MOV DS, EAX		; DS vorbereiten

		MOV DI, 6500h		; Ort der Tastaturcodes
		XOR CH, CH		; Z鋒ler = 0

		DoLng:

			MOV AL, CH	; Speicher 黚erschreiben
			MOV [DI], AL
			ADD CX, 1	; Z鋒ler + 1
			ADD SI, 1
			ADD DI, 1

			CMP CX, 255	; Maximale L鋘ge erriecht?
			JNE SHORT DoLng

	POP DS				; DS zur點kholen


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Willkommensmeldung
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


	MOV SI, MSG_Loaded		; Verweis zum String
	MOV AH, 1			; Funktion Stringausgabe
	INT 21h				; Ausf黨ren


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Lade Startup.bat
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	MOV DI, InputString
	MOV SI, StartupFilename

	ADD DI, 8
	

	WriteStartupF:

		LODSB
		STOSB
		CMP AL, 0
		JNE SHORT WriteStartupF

	JMP NEAR ViewExecute

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Kommandozeileninterpreter
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	XOR AX, AX
	CLC

Begin:

	CALL DeActiveScript

	CLC				; Carry Flag l鰏chen

	MOV SI, Crlf			; Pointer zum String
	MOV AH, 1			; Stringausgabe
	INT 21h				; Ausf黨ren

	MOV SI, Path			; Pointer zum String
	MOV AH, 1			; Stringausgabe
	INT 21h				; Ausf黨ren

	MOV SI, Path			; SI zeigt nach Path
					; Script um "A:\>" oder "A:\DUMMY>" zu schreiben
					; Ermittle Ende des Strings:

	.BeginDo:

		LODSB			; SI nach AL
		CMP AL, 0		; AL = 0?
		JNE SHORT .BeginDo	; wenn nicht, dann neuer Durchlauf

	SUB SI, 2			; SI um zwei zur點k
	MOV AL, [SI]			; AL nach SI

	CMP AL, ':'			; AL = ":"
	JNE SHORT .BeginWasSlash	; Wenn nicht, dann schreibe ">"

	MOV AL, '\'			; Wenn ja, dann schreibe
	MOV AH, 11			; "\"
	INT 21h

.BeginWasSlash:

	MOV AL, '>'			; Zeichen zum ausgeben
	MOV AH, 11			; Zeichenausgabe
	INT 21h			

	MOV AL, 9			; String leeren
	MOV DI, InputString		; Verweis zum SchreibString
	CALL ClearString		; Ausf黨ren
		
	MOV AH, 2			; Befehl einlesen
	MOV DI, InputString		; SchreibString
	INT 21h				; Ausf黨ren

	MOV SI, InputString
	MOV DI, LastCommand

.Save_Command:

	LODSB
	STOSB

	CMP AL, 0
	JNE SHORT .Save_Command

ParseCommand:

	MOV SI, InputString		; SI und ...
	MOV DI, DummyString		; ... DI ...
	CALL UCase			; ... in Gro遙uchstaben umwandeln


CheckIfKeyword:

	;; Zuerst wird der Befehl darauf hin
	;; gepr黤t, ob er ein Program oder Shell Befehl ist:

	;; cd/

	MOV AX, DummyString		; QuellString	
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 3			; 3 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_RootDir		; VergleichsSttring	
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR GoToRootDir		; gleicher String?

	;; cd

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 2			; 3 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_CD			; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ChangeDir		; gleicher String?

	;; dir

	MOV AX, DummyString		; QuellString	
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 3			; 3 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Dir			; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ViewDir			; gleicher String?


	;; ver

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 3			; 3 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Ver			; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ViewVer			; gleicher String?



	;; cls

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 3			; 3 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Cls			; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR Cls			; gleicher String?

	;; exit

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 4			; 4 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Exit		; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ViewExit		; gleicher String?

	;; mem

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 3			; 3 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Mem			; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR MemManager		; gleicher String?

	;; type

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 4			; 4 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Type		; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ViewType		; gleicher String?


	;; echo

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 4			; 4 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Echo		; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ViewEcho		; gleicher String?


	;; pause

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 5			; 4 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Pause		; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ViewPause		; gleicher String?



	;; time

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 4			; 4 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Time		; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR Time			; gleicher String?

	;; date

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 4			; 4 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Date		; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR Date			; gleicher String?

	;; execute

	MOV AX, DummyString		; QuellString		
	MOV DI, AX
	PUSH CX				; CX sichern
	MOV CX, 7			; 4 Zeichen zur Kontrolle
	PUSH AX				; AX sichern
	MOV AX, CMD_Execute		; VergleichsSttring
	MOV SI, AX
	POP AX				; AX zur點k
	PUSH DI				; DI sichern
	REP CMPSB			; Vergleich
	POP DI				; DI zur點k

	JE NEAR ViewExecute		; gleicher String?



	; Wenn es sich nicht um einen Shell Befehl handelt:

	MOV SI, InputString		; Befehl > Dateiname
	MOV DI, FileName		; BSP: "BEFEHL  BIN"
	CALL CommandToFileName

	MOV SI, InputString		; Befehlsparameter
	CALL SaveParameter		; Parameter sichern

	MOV SI, CRLF			; Leere Zeile
	MOV AH, 1			; String Schreiben
	INT 21h				; Ausf黨ren

	CLC

	MOV AH, 9			; Datei ausf黨ren
	MOV DX, FileName		; Dateiname
	MOV AL, 0			; Laufwerk
	MOV BX, 0x8000
	INT 21h	

	
PossibleError:

	CMP AH, 3
	JE NEAR FileNotFound

	CLC

	JMP NEAR Begin			; N鋍hste Befehlseingabe
	

FileNotFound:

	MOV SI, MSG_Fehler		; Verweis zum String
	MOV AH, 1			; Stringausgaben
	INT 21h


	CLC

	JMP NEAR Begin			; N鋍hste Befehlseingabe		

DirNotFound:

	MOV SI, MSG_Dir_Fehler		; Verweis zum String
	MOV AH, 1			; Stringausgabe
	INT 21h

	CLC				; Carry l鰏chen

	JMP NEAR Begin			; N鋍hste Befehlseingabe


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Aktiviert die script Variable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ActiveScript:

	PUSHA

	MOV AX, 50h
	MOV DS, AX
	MOV ES, AX

	MOV AX, 6630h
	MOV SI, AX
	
	MOV WORD [SI], 1

	POPA

	RETN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Deaktiviert die Scriptvariable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DeActiveScript:

	PUSHA

	MOV AX, 50h
	MOV DS, AX
	MOV ES, AX

	MOV AX, 6630h
	MOV SI, AX
	
	MOV WORD [SI], 0

	POPA

	RETN


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Checkt die Scriptvar.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CheckScript:


	MOV AX, 50h
	MOV DS, AX
	MOV ES, AX

	MOV AX, 6630h
	MOV SI, AX

	XOR AX, AX

	MOV AX, [SI]

	RETN


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Wandelt einen String in Gro遙uchstaben um
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

UCase:

	LODSB				; SI > AL; SI + 1
	CALL CharUCase			; AL in Gro遙uchstaben
	STOSB				; AL > DI; DI + 1
	CMP AL, 0			; AL = 0?
	JNE SHORT UCase			; Wenn nicht, dann n鋍hstes Zeichen
	
	RETN				; Funktionsr點ksprung


CharUCase:   

	CMP AL, 'a'			; ist das Zeichen kleiner als 'a'?
	JB .upcase1
	CMP AL, 'z'			; ist das Zeichen gr鲞er als 'z'?
	JA .upcase2		
	SUB AL, 32			; Zeichen = Zeichen - 32
	JMP SHORT .upcase1
	                

	.upcase2:

		CMP AL, '

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -