操作系统开发:BIOS/MBR基础与调试
这里在实验之前需要下载 Bochs-win32-2.6.11 作者使用的是Linux版本的,在Linux写代码不太舒服,所以最好在Windows上做实验,下载好虚拟机以后还需要下载Nasm汇编器,以及GCC编译器,为了能够使用DD命令实现磁盘拷贝,这里你可以安装windows 10 下面的子系统Ubuntu,需要使用命令时可以直接切换。
**注释:**该系列笔记是在学习《操作系统真相还原》时通过阅读后简化并适当描述整理的学习笔记,首先,致敬作者郑刚博士,在读本书时能深刻的感觉到作者写书时一丝不苟的态度,书很厚写的,讲解细致幽默,很能让人愿意继续读下去,同时也不得不佩服作者计算机底层功力的深厚,转载本文请一并附带郑刚版权信息。
BIOS 软件接力第一棒
BIOS 基本输入输出系统,BIOS代码所做的工作是一成不变的,所以他是被固化到ROM中的一块只读区域中,在开机时此ROM会被映射到低端1MB内存的顶部,原因是系统在开启时默认是实地址模式(该模式最大寻址范围0-fffff),所以其寻址范围也就被限制在了0xF0000-x0xFFFFF
区域中,这64KB的内存就是BIOS的执行代码.
在开机的一瞬间,CPU的CS:IP寄存器会被强制初始化为0xF000:0xFFF0
,在实地址模式下该地址需要乘以16也就是左移四位加上偏移地址得到,于是0xF000:0xFFF0
就等效于0xFFFF0
此处的地址距离0xFFFFF
只有16个字节的空间,里面存放着一条jmp far f000:e05b = fe05b
的汇编指令,该指令将跳转到真正的BIOS开始的位置.
接着BIOS将会通过自身的代码对硬件进行自检测,在初始化硬件后,则开始向内存0x000-0x3ff
中初始化数据结构以及拷贝中断向量表,紧接着BIOS将会通过调用int 19h
中断,此中断用以检测计算机中的硬盘,如果检测到0盘0道1扇区末尾的两个字节是0x55,0xaa
则认为此扇区确实存在,于是就会将此区域中的内容,加载到内存7c00的位置,并通过一条jmp far 0:0x7c00h
的指令跳转到该位置执行,这样BIOS就将CPU控制权交给了MBR了,而BIOS将会再次睡去.
MBR 收到跳转来源,继续执行。
此处的7c000就是MBR代码的开始位置,之所以是7C00是因为,DOS中要求最小内存是32KB,而MBR大小必须是512字节(1KB),所以选择32kB中的最后1KB的位置最为合适,32KB(0x8000)-1KB(0x400)=>0x7c00
,这就是7C00的由来,同时还需要保证第510-511字节必须为0x55,0xaa
才可以.
保存以下汇编代码,并使用 nasm -o mbr.bin mbr.asm
编译简易版MBR文件.
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处mov ax,csmov ds,axmov es,axmov ss,axmov fs,axmov sp,0x7c00mov ax,Messagemov bp,ax ; 保存字符串地址mov cx,15 ; 保存字符串长度mov ax,01301h ; 子功能号13是显示字符及属性mov bx,000ch ; 页号位0,使用黑色为背景色,红色为字体颜色mov dl,0int 10h ; 10h中断,用来显示字符retMessage: db "hello lyshark !"
times 510-($-$$) db 0 ; 填充510字节为0
db 0x55,0xaa ; mbr的结束标志
进入Bochs目录下执行bximage.exe
生成一个映像文件,默认是a.img,你可以改名为其他的,这里我定义为linux.img
并将编译好的mbr.bin写入到镜像中
dd if=mbr.bin of=linux.img bs=512 count=1 conv=notrunc
在Bochs目录下新建并编辑bosh.src保存,然后执行bochs.exe -f bosh.src
模拟执行MBR代码.
megs:32
romimage:file=$BXSHARE/BIOS-bochs-latest
vgaromimage:file=$BXSHARE/VGABIOS-lgpl-latest
floppya:1_44=linux.img,status=inserted
boot:floppy
log:bochsout.txt
mouse:enabled=0
keyboard: keymap=$BXSHARE/keymaps/x11-pc-de.map
上方屏幕会比较混乱,这里我们先来进行清屏操作,清屏中断调用也是int10
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处mov ax,csmov ds,axmov es,axmov ss,axmov fs,axmov sp,0x7c00mov ax,0x600 ; 清屏范围,也就是宽度mov bx,0x0mov cx,0x0 ; 清屏 左上角(0,0)mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)int 0x10mov ax,Messagemov bp,ax ; 保存字符串地址mov cx,15 ; 保存字符串长度mov ax,01301h ; 子功能号13是显示字符及属性mov bx,000ch ; 页号位0,使用黑色为背景色,红色为字体颜色mov dl,0int 10h ; 调用10h号中断,用来显示字符retMessage: db "hello lyshark !"
times 510-($-$$) db 0 ; 填充510字节为0
db 0x55,0xaa ; mbr的结束标志
执行结果,如下,但是,打印字符串,在底部,因为光标在底部。
设置光标到顶部,这里百度一下光标中断,发现了。
接着改进代码
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处mov ax,csmov ds,axmov es,axmov ss,axmov fs,axmov sp,0x7c00mov ax,0x600 ; 清屏范围,也就是宽度mov bx,0x0mov cx,0x0 ; 清屏 左上角(0,0)mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)int 0x10mov dh,0x0 ; 设置光标列号mov dl,0x0 ; 设置光标行号mov bh,0x0 ; 页码int 0x10mov ax,Messagemov bp,ax ; 保存字符串地址mov cx,15 ; 保存字符串长度mov ax,01301h ; 子功能号13是显示字符及属性mov bx,000ch ; 页号位0,使用黑色为背景色,红色为字体颜色mov dl,0int 10h ; 调用10h号中断,用来显示字符retMessage: db "hello lyshark !"
times 510-($-$$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
完美结果。
mbr.asm
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处mov ax,csmov ds,axmov es,axmov ss,axmov fs,axmov sp,0x7c00mov ax,0x600 ; 清屏范围,也就是宽度mov bx,0x0mov cx,0x0 ; 清屏 左上角(0,0)mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)int 0x10mov dh,0x0 ; 设置光标列号mov dl,0x0 ; 设置光标行号mov bh,0x0 ; 页码int 0x10mov ax,Messagemov bp,ax ; 保存字符串地址mov cx,15 ; 保存字符串长度mov ax,01301h ; 子功能号13是显示字符及属性mov bx,000ch ; 页号位0,使用黑色为背景色,红色为字体颜色mov dl,0int 10h ; 调用10h号中断,用来显示字符hltretMessage: db "hello lyshark !"
times 510-($-$$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
mbr.src
megs:32
romimage:file=./BIOS-bochs-latest
vgaromimage:file=./VGABIOS-lgpl-latest
boot:disk
mouse:enabled=0
ata0-master: type=disk, path="linux.img", mode=flat, status=inserted
keyboard: keymap=./x11-pc-de.map
填充数据
dd if=mbr.bin of=linux.img bs=512 count=1 conv=notrunc
dd if=/dev/zero of=linux.img seek=1 bs=512 count=2879
运行
bochsdbg -q -f mbr.src
vb sp:0x7c00
c
让我们对显卡说点什么?
上面我们通过调用BIOS提供的int 0x10
中断来实现打印字符操作,但我们在后期必须要借助显卡来输出图像,而显卡是外部设备,必须通过总线来操作。
由于CPU使用的信号是TTL电平,而外部设备都是机械设备,故他们不会使用该电平驱动,这就导致CPU与硬件设备没有办法实现沟通,硬件工程师们提供的方法是,在这两者之间架起一座桥,也就是在CPU和外设之间加上一层IO接口,该接口的作用就是实现CPU和外设之间相互做协调转换。
其次外部设备的种类也是多种多样的,其输出的信号可能是数字信号,也可能是模拟信号,而我们的CPU只能处理数字信号,数字信号需要经过数模转换器<D/A>
成模拟量才能送到外设来驱动硬件工作,模拟量也同样需要经过模数转换器<A/D>
转换成数字量才能被CPU直接处理,所以接口电路中需要包括A/D转换器和D/A转换器。
转换后的数字信号,会经过总线进行传递,总线的别名是BUS,之所以叫做BUS是因为其是公共线路,所有硬件设备都会走此线路,但同一时刻,CPU只能和一个IO接口(寄存器/端口)通信,当有多个IO接口同时想和CPU通信时,那么IO仲裁模块会对其进行竞争与选优,仲裁模块固化到,输入输出控制中心(ICH)也就是南桥芯片上的。
多数情况下,南桥和北桥是成对出现的,南桥主要负责连接PCI,PCI-Express,AGP
等低速设备,而北桥则用于链接高速设备,如内存等。
IO接口都是串行口,其在设计之初就是负责与CPU进行通信的,我们想要与CPU通信,其实是向这些接口中写入数据,同时为了区别CPU中的寄存器,所以把IO接口叫做端口,某些外设可以通过内存映射来访问,即把某些端口映射到指定内存中,访问某个内存区域就相当于访问了指定的端口。
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处mov ax,csmov sp,0x7c00mov ax,0xb800mov gs,axmov ax,0x600 ; 清屏范围,也就是宽度mov bx,0x0mov cx,0x0 ; 清屏 左上角(0,0)mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)int 0x10mov dh,0x0 ; 设置光标列号mov dl,0x0 ; 设置光标行号mov bh,0x0 ; 页码int 0x10mov byte [gs:0x00],'M'mov byte [gs:0x01],0xa4 ; 显示A=绿色闪烁 4=红色mov byte [gs:0x02],'B'mov byte [gs:0x03],0xa5mov byte [gs:0x04],'R'mov byte [gs:0x05],0xa6rettimes 510-($-$$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
Bochs调试命令基础
Bochs调试命令常用的有以下几种.
<bochs:1> vbreak 0x0000:0x7c000 7c000设置断点
<bochs:1> pb 0x7c000 设置物理断点
<bochs:1> vb sp:0x7c00 设置虚拟断点(保护模式)
<bochs:1> info break 显示所有断点状态
<bochs:1> delete num 删除一个断点<bochs:1> c 运行遇到断点停下
<bochs:1> n 执行下一指令
<bochs:1> r 显示寄存器
<bochs:1> u/10 向下反汇编10条
<bochs:1> print-stack 打印堆栈x /nuf addr 查看一个线性地址的内存
xp /nuf addr 查看一个物理地址的内存n 显示多少个字节的内存u 单位长度; one o单位fb 字节h 半字(2 字节)w 字 (4 字节)g 双字 (8 字节)F 打印格式:x 打印十六进制d 打印十进制u 打印无符号十进制o 打印八进制t 打印二进制
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处mov ax,csmov sp,0x7c00mov ax,0xb800mov gs,axmov ax,0x600 ; 清屏范围,也就是宽度mov bx,0x0mov cx,0x0 ; 清屏 左上角(0,0)mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)int 0x10mov dh,0x0 ; 设置光标列号mov dl,0x0 ; 设置光标行号mov bh,0x0 ; 页码int 0x10mov byte [gs:0x00],'L'mov byte [gs:0x01],0xa4 ; 显示A=绿色闪烁 4=红色mov byte [gs:0x02],'y'mov byte [gs:0x03],0xa5mov byte [gs:0x04],'S'mov byte [gs:0x05],0xa6mov byte [gs:0x6],'h'mov byte [gs:0x7],0xa7mov byte[gs:0x8],'a'mov byte [gs:0x9],0xa6mov byte[gs:0xa],'r'mov byte [gs:0xb],0xa5mov byte[gs:0xc],'k'mov byte [gs:0xd],0xa4hltrettimes 510-($-$$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
循环显存
_start:; 清屏和设置光标位置mov ax,0x600 ; 清屏范围,也就是宽度mov bx,0x0mov cx,0x0 ; 清屏 左上角(0,0)mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)int 0x10mov dh,0x0 ; 设置光标列号mov dl,0x0 ; 设置光标行号mov bh,0x0 ; 页码int 0x10;初始化数据段,使其指向段基址0X7C0处,即Boot代码被加载的地方mov ax, 0x07c0 ; 设置加载基址mov ds, ax;将文本显示内存段基址 放在ES中,供后面显示字符使用mov ax, 0xb800 ; 设置显存地址mov es, axmov cx, msglen ; 获取字符串长度mov si, message ; 设置字符串基址xor di, diloop_str:mov al, [si] ; 每次取出一个字符mov [es:di], al ; 将字符逐一赋值到显存中inc siinc dimov byte [es:di], 0x07 ; 设置字体颜色inc diloop loop_strhlt ; 程序在此处终止message db "Loading MBR..."msglen db $ - messagetimes 510-($-$$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
Bochs 调试命令
CPU加电后,会跳转到 0xffff0 处,我们可以反汇编这段内存地址,向下反汇编10条。
分别显示,CPU模式,中断,call调用源。
设置vb虚拟地址断点,pb设置物理地址断点。blist显示所有断点。
bpd禁用断点,bpe启用断点。del删除断点。
info idt = 显示中断向量表 , gdt 全局描述符表,ldt 局部描述符表,tss 任务状态段,ivt 中断向量表
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处; 清屏和设置光标位置mov ax,0x600 ; 清屏范围,也就是宽度mov bx,0x0mov cx,0x0 ; 清屏 左上角(0,0)mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)int 0x10mov dh,0x0 ; 设置光标列号 左上角(0,0)mov dl,0x0 ; 设置光标行号 右下角(0,0)mov bh,0x0 ; 页码int 0x10; 初始化,使SP寄存器指向段基址0X7C0处,GS指向显存基地址mov ax,csmov sp,0x7c00mov ax,0xb800mov gs,ax ; 设置显存地址; 设置字符串长度与字符串基地址mov cx, msglen ; 获取字符串长度mov si, message ; 设置字符串基址xor di, di ; 每次清空di寄存器loop_str:mov al, [si] ; 每次取出一个字符mov [gs:di], al ; 将字符逐一赋值到显存中inc siinc dimov byte [gs:di], 000ch ; 设置字体颜色inc diloop loop_strhlt ; 程序在此处终止;message db "Hello LyShark...",0ah,0dh
message db "Hello LyShark..."
msglen equ $ - messagetimes 510-($-$$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
相关文章:

操作系统开发:BIOS/MBR基础与调试
这里在实验之前需要下载 Bochs-win32-2.6.11 作者使用的是Linux版本的,在Linux写代码不太舒服,所以最好在Windows上做实验,下载好虚拟机以后还需要下载Nasm汇编器,以及GCC编译器,为了能够使用DD命令实现磁盘拷贝&#…...
华为OD机试真题JAVA实现【数组合并】真题+解题思路+代码(20222023)
🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出示例一输入输出示例二输入输出解题思路核心知识点...
说说Real DOM和Virtual DOM的区别?优缺点?
说说Real DOM和Virtual DOM的区别?优缺点?Real DOM(真实的DOM)真实dom的优缺点?Virtual DOM(虚拟的DOM)虚拟dom的优缺点?两者的区别Real DOM(真实的DOM) 在页面渲染出的每个节点都是一个真实的DOM结构 <div class"root&…...

使用脚本以可读的 JSON 格式显示 curl 命令输出
在我们经常调试微服务或者使用 Elasticsearch API 时,经常会使用curl 来进行调试。但是有时我们的输出不尽如意。显示的不是一 pretty 格式进行输出的。我们有时还必须借助于其他的一些网站工具,比如 Best JSON Formatter and JSON Validator: Online JS…...
计算机网络9:HTTP和HTTPS的区别
1.HTTP和HTTPS的区别 (1)安全性 HTTP是超文本传输协议,信息传输存在安全问题HTTPS是安全套接字超文本传输协议,在TCP和HTTP之间加入了SSL/TLS安全协议,进行加密传输 (2)连接步骤HTTP建立相对简…...
Spring+SpringMVC+SpringBoot+MyBatis面试题
什么是Spring框架?使用Spring框架的好处是什么?Spring是一款开源的轻量级Java开发框架,可以提高开发人员的开发效率以及系统的可维护性。Spring框架是很多模块的集合,使用这些模块可以很方便地协助我们进行开发,比如说…...

ContextCapture Master 倾斜摄影测量实景三维建模技术
ContextCapture实景建模大师是一套无需人工干预,通过影像自动生成高分辨率的三维模型的软件解决方案。它集合了全球最先进数字影像处理、计算机虚拟现实以及计算机几何图形算法,在易用性、数据兼容性、运算性能、友好的人机交互及自由的硬件配置兼容性等…...

MySQL事务
文章目录MySQL事务事务的四个特性 ACID事务提交的类型事务的使用MySQL事务 事务是什么? 事务就是一组逻辑操作单元,是数据从一种状态变成另外一种状态。整个单元有一个或多个SQL语句构成,在这个操作单元中,每一个SQL语句相互依赖…...

CData Drivers for Acumatica
CData Drivers for Acumatica Acumatica的CData驱动程序为用户提供了使用AcumaticaERP数据的便捷途径,该数据来自商业智能、分析、定制应用程序、报告以及ETL。通过JDBC、ADO.NET和ODBC等标准驱动程序,以及与PowerShell、Power BI、Excel、SSIS等流行应用…...

智慧税务+数据可视化:企业财务管理告别难题
一、引言在发展社会主义市场经济的过程中,税收承担着组织财政收入、调控经济、调节社会分配的职能。中国每年财政收入的90%以上来自税收,其地位和作用越来越重要,可称之为国家经济的“晴雨表”,有效进行税务管理、充分挖掘税务大数…...

Ansible中常用的模块
目录 一、Ansible Ad-Hoc命令集 1 Ad-hoc 使用场景 2 Ansible的并发特性 3 Ansible-doc用法 4 ansible命令运行方式及常用参数 5 ansible的基本颜色代表 6 ansible中的常用模块 command模块 shell模块 script模块 copy模块 fetch模块 unarchive模块 archive模块…...
问:你是如何进行react状态管理方案选择的?
前言:最近接触到一种新的(对我个人而言)状态管理方式,它没有采用现有的开源库,如redux、mobx等,也没有使用传统的useContext,而是用useState useEffect写了一个发布订阅者模式进行状态管理&…...
【华为OD机试真题 java、python、jsNode】任务总执行时长【2022 Q4 100分】
代码请进行一定修改后使用,本代码保证100%通过率,本题提供了 java、python、JsNode三种代码 题目描述 任务编排服务负责对任务进行组合调度。参与编排的任务有两种类型,其中一种执行时长为taskA,另一种执行时长为taskB。任务一旦开始执行不能被打断,且任务可连续执行。服…...
react基础
react组件传参 父传子 父组件 < ChildA value{this.state.num}></ChildA> 子组件 {props.value}接收父组件传入参数 ChildA.defaultProps{vaue:1} defaultProps默认参数 子传父 props回调函数形式 父 setNum>v>this.setState({num:v}) v形参 < ChildA…...

【Spark分布式内存计算框架——Spark SQL】2. SparkSQL 概述(上)
第二章 SparkSQL 概述 Spark SQL允许开发人员直接处理RDD,同时可以查询在Hive上存储的外部数据。Spark SQL的一个重要特点就是能够统一处理关系表和RDD,使得开发人员可以轻松的使用SQL命令进行外部查询,同时进行更加复杂的数据分析。 2.1 前…...

Kubeadm搭建K8S
目录 一、部署步骤 1、实验环境 2、环境准备 3、所有节点安装Docker 4、 所有节点配置K8S源 5、所有节点安装kubeadm,kubelet和kubectl 6、部署 kubernetes Master 节点 7、token制作 8、k8s-node节点加入master节点 9、 master节点安装部署pod网络插件&a…...
【技术分享】搭建java项目引入外部依赖教程
文章目录引言如何在linux中编译运行java程序IDEA中新建一个简单的java工程项目并运行IDEA中如何引入外部依赖并运行maven引入log4j jar包手工引入log4j jar包如何使用命令行的方式添加外部依赖如何新建一个spring源码项目并为其添加依赖给定一个spring工程源码,如何…...

算法 ——世界 二
个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。个人爱好: 编程,打篮球,计算机知识个人名言:海不辞水,故能成其大;山不辞石…...
数据治理CDGP选择题 4
5、根据DMBOK2,在实施数据治理时,要注重数据标准的建设,以下关于数据标准的描述,哪个选项是不正确的? (知识点: CDGP仿真题)A.数据标准必须得到有效沟通、监控,并被定期审查和更新;最重要的是,必须有强制手…...

动态规划之01背包问题和完全背包问题
01背包的问题描述:(内容参考代码随想录)有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。问题示例&#…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...