当前位置: 首页 > news >正文

操作系统开发: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版本的&#xff0c;在Linux写代码不太舒服&#xff0c;所以最好在Windows上做实验&#xff0c;下载好虚拟机以后还需要下载Nasm汇编器&#xff0c;以及GCC编译器&#xff0c;为了能够使用DD命令实现磁盘拷贝&#…...

华为OD机试真题JAVA实现【数组合并】真题+解题思路+代码(20222023)

🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出示例一输入输出示例二输入输出解题思路核心知识点...

说说Real DOM和Virtual DOM的区别?优缺点?

说说Real DOM和Virtual DOM的区别&#xff1f;优缺点&#xff1f;Real DOM(真实的DOM)真实dom的优缺点&#xff1f;Virtual DOM(虚拟的DOM)虚拟dom的优缺点&#xff1f;两者的区别Real DOM(真实的DOM) 在页面渲染出的每个节点都是一个真实的DOM结构 <div class"root&…...

使用脚本以可读的 JSON 格式显示 curl 命令输出

在我们经常调试微服务或者使用 Elasticsearch API 时&#xff0c;经常会使用curl 来进行调试。但是有时我们的输出不尽如意。显示的不是一 pretty 格式进行输出的。我们有时还必须借助于其他的一些网站工具&#xff0c;比如 Best JSON Formatter and JSON Validator: Online JS…...

计算机网络9:HTTP和HTTPS的区别

1.HTTP和HTTPS的区别 &#xff08;1&#xff09;安全性 HTTP是超文本传输协议&#xff0c;信息传输存在安全问题HTTPS是安全套接字超文本传输协议&#xff0c;在TCP和HTTP之间加入了SSL/TLS安全协议&#xff0c;进行加密传输 &#xff08;2&#xff09;连接步骤HTTP建立相对简…...

Spring+SpringMVC+SpringBoot+MyBatis面试题

什么是Spring框架&#xff1f;使用Spring框架的好处是什么&#xff1f;Spring是一款开源的轻量级Java开发框架&#xff0c;可以提高开发人员的开发效率以及系统的可维护性。Spring框架是很多模块的集合&#xff0c;使用这些模块可以很方便地协助我们进行开发&#xff0c;比如说…...

ContextCapture Master 倾斜摄影测量实景三维建模技术

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

MySQL事务

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

CData Drivers for Acumatica

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

智慧税务+数据可视化:企业财务管理告别难题

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

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状态管理方案选择的?

前言&#xff1a;最近接触到一种新的&#xff08;对我个人而言&#xff09;状态管理方式&#xff0c;它没有采用现有的开源库&#xff0c;如redux、mobx等&#xff0c;也没有使用传统的useContext&#xff0c;而是用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&#xff0c;同时可以查询在Hive上存储的外部数据。Spark SQL的一个重要特点就是能够统一处理关系表和RDD&#xff0c;使得开发人员可以轻松的使用SQL命令进行外部查询&#xff0c;同时进行更加复杂的数据分析。 2.1 前…...

Kubeadm搭建K8S

目录 一、部署步骤 1、实验环境 2、环境准备 3、所有节点安装Docker 4、 所有节点配置K8S源 5、所有节点安装kubeadm&#xff0c;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工程源码&#xff0c;如何…...

算法 ——世界 二

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。个人爱好: 编程&#xff0c;打篮球&#xff0c;计算机知识个人名言&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石…...

数据治理CDGP选择题 4

5、根据DMBOK2&#xff0c;在实施数据治理时&#xff0c;要注重数据标准的建设&#xff0c;以下关于数据标准的描述&#xff0c;哪个选项是不正确的? (知识点: CDGP仿真题)A.数据标准必须得到有效沟通、监控&#xff0c;并被定期审查和更新;最重要的是&#xff0c;必须有强制手…...

动态规划之01背包问题和完全背包问题

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

MATLAB算法实战应用案例精讲-【图像处理】数字图像灰度化(附Java、python、matlab和opencv代码实现)

目录 前言 几个相关概念 1、RGB 2、ARGB 3、灰度化 4.图像点运算 5.线性点运算...

Linux(强大的yum命令)

yum 读 [jʌm] &#xff0c;中文谐音&#xff1a; 样安ing。 yum&#xff08; Yellow dog Updater, Modified&#xff09;是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包管理器。 基于 RPM 包管理&#xff0c;能够从指定的服务器自动下载 RPM 包并且安装&#x…...

28.结语

文章目录28 Epilogue 结语28 Epilogue 结语 Don’t let it end like this. Tell them I said something. 不要让它就这样结束。 告诉他们我说了些什么 —Pancho Villa 您已到达旅程的尽头。 辛苦了 我们希望您能从本书中找到一些有价值的收获。 我们建议该列表应包括以下内…...

ICRS、GCRS、CIRS、TIRS和ITRS坐标系统简介

ICRS、GCRS、CIRS、TIRS和ITRS坐标系统简介1. 简介2. ICRS、GCRS、CIRS、TIRS和ITRS分别介绍2.1 ICRS详细说明2.2 GCRS详细说明2.3 CIRS详细说明2.4 TIRS详细说明2.5 ITRS 详细说明1. 简介 ICRS、GCRS、CIRS、TIRS和ITRS都是天文学中使用的坐标系统&#xff1a; ICRS (Intern…...

你是真的“C”——详解结构体知识点

你是真的“C”——详解结构体知识点&#x1f60e;前言&#x1f64c;什么是结构体&#xff1f;&#x1f64c;1. 结构体的声明&#x1f64c;1.1 结构的基础知识1.2 结构的声明1.3 结构成员的类型1.4 结构体变量的定义和初始化2. 结构体成员的访问&#x1f64c;3结构体传参&#x…...

2023新华为OD机试题 - 单词接龙(JavaScript) | 刷完必过

单词接龙 题目 单词接龙的规则是: 可用于接龙的单词,首字母必须要与前一个单词的尾字母相同; 当存在多个首字母相同的单词时,取长度最长的单词; 如果长度也相等,则取字典序最小的单词; 已经参与接龙的单词不能重复使用; 现给定一组全部由小写字母组成的单词数组, 并指…...

第一章 一般错误信息 - 错误代码 0 到 99

文章目录第一章 一般错误信息 - 错误代码 0 到 99一般错误信息错误代码 0 到 99第一章 一般错误信息 - 错误代码 0 到 99 一般错误信息 错误代码被报告为 ERROR #nnn。这些错误代码有时称为 %Status 错误代码。 可以使用 DisplayError() 和 Error() 方法确定指定错误代码的错…...

MyBatis 之一(概念、创建项目、操作模式、交互流程)

1. MyBatis 是什么MyBatis 是一款优秀的持久层框架MyBatis 也是一个 ORM &#xff08;Object Relational Mapping&#xff09;框架&#xff0c;即对象关系映射它支持自定义 SQL、存储过程以及高级映射MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作MyBatis…...

学习笔记:文件

因为有的数据&#xff0c;数据量极大。或者是你想把编译输出的内容存储起来&#xff0c;就可以使用文件 读文件中内容具体操作 来自C语言详解 FILE文件操作 - 知乎 (zhihu.com) 写入文件具体操作 同样来自 C语言详解 FILE文件操作 - 知乎 (zhihu.com) 当文件关闭时&#xff0c…...

高考结束了以后应该做的事情(个人经历的总结)

高考结束了以后应该做的事情 在本指导中&#xff0c;我总结了我大学期间我认为做的没有后悔&#xff0c;最正确的事情。同时&#xff0c;根据我的经历和我踩过的坑总结出来了这一份入学指南。 这个指导有点偏向于工科生&#xff0c;已经尽量偏向于所有专业了。对于所有专业的同…...

网站 翻页 实现/seo关键词优化排名外包

bitsCN.commysql-utilities工具体验我主要体验了下几个关于REPLICATION的工具。先说下我的环境&#xff1a;MASTER: 192.168.1.131SLAVE: 192.168.1.132, 192.168.1.133三台DB都有对外的ALL权限用户。各个配置文件如下&#xff0c;[sql][rootmysql56-master home]# cat /etc/my…...

仿爱范儿网wordpress主题/seo服务外包公司

以前写过一个沉浸式状态栏 的实现方式 Android 沉浸式状态栏 实现方式一 现在有个更为简单的实现方式 。 相关链接 http://www.apkbus.com/forum.php?modviewthread&tid255929&extrapage%3D3%26filter%3Dsortid%26orderby%3Ddateline%26sortid%3D12 1、效果图 demo 的…...

江苏嘉隆工程建设有限公司网站/商城全网推广运营公司

开始学javascript&#xff0c;写作业。 <script type"text/javascript"> function toChinese(money){var chNum[零,壹,贰,叁,肆,伍,陆,柒,捌,玖];var maxnum999999999999.99;var chstr , //返回的大写字符串moneyintparseInt(money),//整数位moneydec money.t…...

网站建设属于什么支出/杭州seo排名优化外包

为什么80%的码农都做不了架构师&#xff1f;>>> 常见的数据库优化方法&#xff1a;索引&#xff08;数据库&#xff09;&#xff0c;缓存&#xff0c;分表&#xff0c;分库&#xff0c;sql优化。 索引&#xff1a;创建索引一般有以下两个目的&#xff1a;维护被索引…...

不用域名推广网站/最近热点新闻事件

上篇博客《SSH快速进阶——struts2简单的实例》中&#xff0c;处理用户登陆的action—LoginAction为&#xff1a; package com.danny.user.action;public class LoginAction {private String username;private String password;public String getUsername() {return username;…...

如何在微信小程序上开店/石家庄网站seo

LibModule配置更新9 months ago app配置更新9 months ago gradle/wrapper配置更新9 months ago screenshotsreadmea year ago .gitignore重建gradle 结构的示例a year ago LICENSE.TXTLICENSEa year ago README.md一些配置更新9 months ago build.gradle配置更新9 months ago s…...