USTB
大一:高等数学、C/C++、离散数学
大二:计算机组成原理、数字电路、数据结构、线性代数
大三:编译原理、操作系统、模拟电路、网络原理、汇编相关课程、概率论
要自学计算机专业课的话,一般先学C语言(系统编程的基础,最经典的过程式程序设计语言)和离散数学(计算机科学的数学基础);
然后学习数据结构(所有专业课的基础)和计算机系统基础(这其中包括汇编);
。模拟电路和计算机专业知识几乎没有任何关系,自学的话不建议学
数字电路-组成原理是一条线,操作系统是一条线,计网是一条线,编译是一条线,算法是一条线,C++等面向对象语言是一条线,这些不分先后都可以按需学习
功能,可靠性,可用性,效率
可维护,可移植,兼容性(Compatibility)
功能是否完备, 是软件质量的核心,正确地执行所需的功能
在一定时间内能够持续正常地运行
易于使用
消耗的资源量,包括时间、内存和磁盘空间等
--->
容易维护和修改
容易在不同的平台上运行
能够与其他软件和硬件兼容
架构设计原则
编程第一原则:先把东西做出来
* 代码要可读
● 要有注释,但不能太多,单行注释足够了 #xxx
● 网络不安全,所以不会滚动更新
● 时间效率,高于空间效率
● 没有包管理器,每个软件都是一体的,和依赖要在一起
● 库很重要, 和flatpack一样默认没有任何仓库,有一个中央仓库,可以自建,可以用git/svn管理
● 约定大于配置, spec描述文件
● 变量小写,常量大写
● 必须有输出 bin/ lib/ ScriptSpec Specfile
● 数据和类型一体,不可分割
指令系统 8类
A算数arithmetic,B逻辑bit,C控制control => ALU
U字符unicode,V向量vector,G图连接graph
X,Y 扩展,动态引擎,运行时引擎 java,js,gui,axv多媒体
表示数据
表示数字 0xFF 8bit 或 0xFFFF 16bit
表示字符串 u'asdf' 或 'adsf' 不要双引号
int num = 'a' 这是一个ASCII编码
标准库
c语言 #include <stdint.h> c++11 #include <cstdint>
https://www.runoob.com/cplusplus/cpp-libs-cstdint.html
// 声明固定宽度的整数类型
int8_t a = -128; // 最小值
uint8_t b = 255; // 最大值
int16_t c = -32768;
uint16_t d = 65535;
int32_t e = -2147483648;
uint32_t f = 4294967295U; // 使用 U 后缀表示无符号常量
int64_t g = -9223372036854775807LL; // 使用 LL 后缀表示长长整型常量
uint64_t h = 18446744073709551615ULL; // 使用 ULL 后缀表示无符号长长整型常量
INT8_MIN, INT8_MAX, UINT8_MAX
INT16_MIN, INT16_MAX, UINT16_MAX
INT32_MIN, INT32_MAX, UINT32_MAX
INT64_MIN, INT64_MAX, UINT64_MAX
仓库/模块/包
一切皆文件
include包含, 没有包管理器, 只有文件和目录 两种东西
没有 module /require/ import /namespace之类的东西,每个文件就是一个模块(不声明module)
include "xxx.tsc" 引入所有, 隐式模块
include "xxx" 引入 xxx/* , 显式模块
目录可以包含任意文件 xxx/
VERSION
VERSION.tsc
相对位置,不能只导入一部分,文件文件无法分割
#include "VERSION"
#include "VERSION.rst"
util = include("util.tsc")
util = include "util.tsc"
# 入口可以任意文件名
index, main, index.tsc, __init__
# 描述文件Specfile, 有约定和约束
不使用json,xml 使用自己的脚本语言
XXX = Specification()
XXX::Specification
env: bash
类型系统独立
使用protoc兼容
type + c-like/c-link + assembly
类型(auto), 函数, 结构体, 模块
注释# 多条语句; 行尾可以加也可以不加
方案1
常量
A = 10
PI = 3.12
NUL
变量
a = 10; b = "eee"
a = int 是类型,也是初值
a = int(10) 是类型,也是函数
b = bytes
语句块函数块,是否等价; 不等价,函数全局,为了复用
语句块可以加{}也可以不加,缩进足够了; 函数只能用关键字声明
if TRUE
...
else if TRUE
...
else
...
输出到控制台
message("lll ${name}, ls {:name}")
message("lll ${name}, ls {:name}", ctx)
返回状态码 OK, exitCode
def add(a,b, out c)
c = a + b
enf
a = 10; b = 20
c
add(a,b,c)
C语言没有异常处理,只处理error
def add(a=int, b=bytes, out c=int)
return //什么都不返回,终止
exit("asdf") 错误信息
exit(-2) 错误码
enf
特殊指令
#!/bin/bash
include "xxx"
方案2
fn = add(a,b,c) // return Function Type
fn.params
fn.args
fn.value // return 不throw new Error("asdf")除了OK,全是异常
fn.result
if (fn == NUL) 重写运算符,比较 fn.value == NUL
结构体类型
typedef Stu(int,bytes) // 没有string,本质是bytes
ss = Stu(10, "adf3")
ss = Stu
ss[0]
ss[1]
结构体类型2
typedef Stu(id = int, name = bytes)
ss = Stu(10,"ss") 声明 + 赋值
ss = Stu 声明 + 初值
ss.name
ss.id
值类型value, return Value Type; rename type
typedef Stu = int
ss = Stu(10) // 等价 ss = int(10)
ss = Stu // 等价 ss = int
ss = 10
元组类型 Tuple, Array
typedef Stu = [int,bytes]
ss = Stu([10, "www"])
ss = Stu
ss = [10, "234"] // return Array Type
ss[0]
ss[1]
初始化函数
typedef Stu(id = int, name = bytes)
$id++
endf
属性顺序最重要,为了序列化; 有构造,没有析构
值类型
typedef Person = int
typedef Person::id = int
基础类型
typedef Person(id = int, name=bytes)
enf
typedef Person
id = int
name = bytes
enf
p = Person; p.id = 12; p.name = "asdf"
p = Person {
id = 32 # 属性初始化
name = "asdf
}
p = Person(12)
p = Person(12, "asdf")
继承有用吗,为了少写几个属性,还是为了继承方法
typedef Student
id = int # 优先级最高,解释型就是这样,先定义先使用
name = bytes # 显示类型会覆盖隐式类型,就像maven依赖一样
::Person # 所有Person属性
::Person2 # 所有Person2属性
Person:: # 所有Person属性, 这个比较好
Person::*
Person::{id,name}
enf
s = Student(10, n)
方案3
fn = add(a,b,c) // return Function Type
fn.params
fn.args
fn.value // return 不throw new Error("asdf")除了OK,全是异常
fn.result
if (fn == NUL) 重写运算符,比较 fn.value == NUL
结构体类型
typedef Stu(int,bytes) // 没有string,本质是bytes
ss = Stu(10, "adf3")
ss = Stu
ss[0]
ss[1]
结构体类型2
typedef Stu(id = int, name = bytes)
ss = Stu(10,"ss") 声明 + 赋值
ss = Stu 声明 + 初值
ss.name
ss.id
值类型value, return Value Type; rename type
typedef Stu = int
ss = Stu(10) // 等价 ss = int(10)
ss = Stu // 等价 ss = int
ss = 10
元组类型 Tuple, Array
typedef Stu = [int,bytes]
ss = Stu([10, "www"])
ss = Stu
ss = [10, "234"] // return Array Type
ss[0]
ss[1]
初始化函数
typedef Stu(id = int, name = bytes)
$id++
endf
废弃
ss: Stu = 10
typedef Stu(id: int, name: bytes)
8421 BCD编码
2 + 3 = 0010 + 0011 = 0101 = 5 ; 结果<=9 正常
2 + 9 = 0010 + 1001 = 1011 ; 结果 >9, 修正结果+6 1000/0001 = 11
2421 编码
0000 -> 0
0001 -> 1
0010 -> 2
0011 -> 3=2+1
0100 -> 4
1011 -> 5=2+0+2+1
1100 -> 6=2+4
1101 -> 7=2+4+0+1
1110 -> 8=2+4+2+0
1111 -> 9=2+4+2+1
字符编码 (unicode)
https://wuli.wiki/online/encode.html
https://www.cnblogs.com/xtuz/p/12448200.html
NUL 字符是 ascii 表中编号为 0 的字符,也就是说在该子节中,所有的比特都为零
NUL 字符通常用于 C 语言的字符串的最后代表字符串结束,但几乎不用于文本文件中(无论使用哪种编码)
> ASCII 编码,每个字符占据1bytes
用二进制表示的话最高位必须为0(扩展的ASCII不在考虑范围内),因此ASCII只能表示128个字
目前世界上除ASCII之外的其它通行的字符编码方案,基本上都兼容ASCII,但相互之间并不兼容
> ANSI编码,表示英文字符时用一个字节,表示中文用两个字节
遇到字节是以0开头的,就知道这一个字节就表示了一个字符;遇到字节是以1开头的,就知道要加上下一个字节合起来表示一个字符
必须是两个大于127的字节连在一起来共同表示一个汉字(GB2312为双字节编码),前一字节称为高字节,后一字节称为低字节
在GB2312中收录了6763个汉字以及682个特殊符号,已经囊括了生活中最常用的所有汉字
简体中文系统下,ANSI 编码可以是 GB2312 或者 GBK 编码,在日文操作系统下 ANSI 编码代表 JIS 编码
> Unicode 编码,ISO规定每个字符必须使用两个字节
对于ASCII编码表里的字符,保持其编码不变,只是将长度扩展到了16位,其他国家的字符全部统一重新编码
| 中文字符 | ANSI(GBK) | Unicode | UTF-8 |
|---|---|---|---|
| 中 | 0xD6D0 | 0x4E2D | 0xE4B8AD |
字/半字
数据总线16bit, 32bit, 64bit
32 位系统,字 = 32bit = 4byte
64 位系统,字 = 64bit = 8byte
龙芯 bit b, Byte B, Word W 32b, Halfword H 16b, Doubleword D 64b
NASM 和 C
FC/NES 用 6505汇编NESASM, GBA开始用C 32bit。FC的资料比GBK多
NES好理解 https://happysoul.github.io/nes/asm_cn/
直接控制硬件,图形,声音,输入输出
ROM, RAM
PRG / Program Memory / code of game / ROM
CHR / Character Memory / data of graphisc / RAM or ROM
CPU, Picture PU, Audio PU
现在绝大部分单片机都用C,公司不要求汇编
单片机 http://www.51hei.com/bbs/dpj-227533-1.html
汇编 https://cs.lmu.edu/~ray/notes/nasmtutorial/
sudo apt install nasm
nasm --help
sudo apt install sasm 非常难用
sudo apt install gcc-multilib 会重启所有服务
IDE
nasm -felf64 hello.asm && ld hello.o && ./a.out
GTK 和 Qt
https://www.kancloud.cn/apachecn/zetcode-zh/1950323
https://developer.aliyun.com/article/1245602
https://notes.leconiot.com/gtk.html
$sudo apt-get install libgtk-3-dev
$sudo apt-get source libgtk-3-dev
$sudo apt-get install automake
$./configure --prefix=/opt/gtk3
$make
$make install
编程也是编码
编程与编码,都是二进制; bin 目录,bin文件,二进制Binary;asci 编码, u8编码
代码段 .text 指令流code
数据点 .data 数据流data
指令 + 变量 + 控制流
code 指令,ByteCode 字节码
data 数据,bytes = (string = byte[])
函数也是命令
Exit Status
Return Value
shell buildin 内建命令
type cd
type -a echo 外部命令
/usr/bin/echo
Stack Based Machine
栈机用内存,寄存器用CPU。 以后内存会越来越快
基于栈的优点是可移植性更好、指令更短、实现起来简单,但不能随机访问栈中的元素,完成相同功能所需要的指令数也比寄存器的要多,需要频繁的入栈和出栈。
基于寄存器的优点是速度快,有利于程序运行速度的优化,但操作数需要显式指定,指令也比较长。
关键点
* 栈机,龙芯指令 2^7 用ASCII编码 (参考JVM指令集)
https://javabetter.cn/jvm/zijiema-zhiling.html
* 指令和数据分离,数据是根本,计算机本质是数据,算法本质是指令。
* 兼容性有限,必要的程序换一个java native env环境运行,或者用C写,用汇编写
* SQL存储过程
* 类型是必要的,默认只有 Number 和 Text, 常量, 标准SQL类型 推断
https://www.runoob.com/sql/sql-datatypes-general.html
* 引入其他类型stdlib.h java.h
cpuid 十进制计算机 ABCDEF 表示指令, 0123456789 表示数据
模拟 8bit 计算器。先用软件实现Qt, Java
物理 64bit 计算机。二进制编码,存储系统,指令系统
VT 两种模式
V全模拟全APP,与 Runtime 绑定
T高性能单APP,与 Runtime 分离
网络计算机,时间必须同步
Linux 内核
GNU 工具
Linux 桌面环境
应用软件
> 发行版 LiveCD
Lua Based Language
https://www.lua.org/versions.html
[openEuler]
yum install -y gcc
[anolis]
yum install -y gcc make
## lua 5.3依赖 (5.4不依赖)
yum install -y readline-devel
##
readline 是基础库,openeuler和anolis都有
## 教程:写一个编程语言
Building a Programming Language
https://classpert.com/classpertx/courses/building-a-programming-language/cohort
函数有返回值, 过程没有
typedef xxx
return 10
enf
aa = xxx() // aa = 10
if (aa != nil) ...
if (aa) ...
https://c-cpp.com/c/program/EXIT_status.html
没有返回值, 本质是 int main(void) 只返回执行状态
def yyy
return 10
exit(1);
exit(EXIT_FAILURE);
return EXIT_SUCCESS;
enf
aa = xxx() // aa = FunctionReturn{exitCode, retValue,} {error,value)
aa.value // 类似Optional<int>
if (aa)
ExitCode
System.exit(int status)
C语言 <stdlib.h>
EXIT_SUCCESS 或为零
EXIT_FAILURE
OK 0
WARN 5
ERROR 10
FAILURE 20
0: Success—Indicates that the command or program executed successfully without any errors.
1: General Error—A catch-all exit code for a variety of general errors. Often used when the command or program encounters an error, but no specific exit code is available for the situation.
2: Misuse of shell built-ins—Indicates incorrect usage of shell built-in commands or misuse of shell syntax.
126: Command cannot execute—The command was found, but it could not be executed, possibly due to insufficient permissions or other issues.
127: Command not found—The command was not found in the system's PATH, indicating that either the command does not exist or the PATH variable is incorrectly set.
128: Invalid exit argument—Returned when a script exits with an invalid argument. This usually indicates an error in the script itself.
128 + N: Fatal error signal N—Indicates that the command or program was terminated by a fatal error signal. For example, an exit code of 137 (128 + 9) means that the command was terminated by a SIGKILL signal.
130: Script terminated by Control-C—Indicates that the command or script was terminated by the user using Control-C (SIGINT signal).
255: Exit status out of range—Returned when the exit status is outside the valid range (0 to 254).
关键字 Keyworkd (尽量生僻一点,不要让所有人避讳)
def / enf
typedef / enf
call, syscall
exec aaaa / aaaa()
------
函数是头等公民,为了区分代码块,不适用 { } 或者 begin/end do/end 包围函数体
第一行是声明,格式固定 或者到 (参数结尾)
def aaa
enf
def a2(aaa)
def a3(p1,p2
,p3)
------ 函数也是类型,可以作为参数
函数实际名称
def aaa ==> aaa, aaa_*
def aaa() ==> aaa, aaa_0
def aaa(p1,p2) => aaa_2
def aaa(.number p1, .number p2) => aaa_2_i_i
(.number p1 .string p2 .exec aaa) 名称只是为了捕获传参
_i
_f // float 还是 function 有歧义
-------- 函数内声明子函数
sub marine {
$n += 1; # Global variable $n
print "Hello, sailor number $n!\n";
}
f1(a,b) = {}
[function] f1(aa, bb) {
}
f1()
编译脚本 执行./build.sh 类似 gradle (build.bat 和 build)
spec: v1.2 // 规范(cmake最低版本)
name: xxxx
project = xxxx
version = v1.2
source = ./src
target = ./dist
set(X2_VERSION) // 内置全局变量,内置函数
set(CC = '') //全局变量,源码使用 $CC获取
set(GCC = '')
set(CXX = '')
// default value, gcc
clink('system dir') {
include <aaa.h>
-lpng
-lm
}
set(JAVA_HOME='')
set(JAVAC = '')
set(JAVA = '')
// default value, jdk
jlink('mavem repo') {
import "net.aaa.bb:cc:1.2"
}
作用域 do...end
-------- lua
do
local a2 = 2*a
local d = sqrt(b^2 - 4*a*c)
x1 = (-b + d)/a2
x2 = (-b - d)/a2
end -- scope of `a2' and `d' ends here
print(x1, x2)
https://www.runoob.com/linux/linux-shell-process-control.html
--------- shell
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done