part 1
8.27
方便管理,主要是想熟悉下git的操作
先创建并且切换到一个新的分支:
git commit --allow-empty -am "before starting PA1"
git checkout -b PA1
其中--allow-empty
表示允许提交一个空的提交,git默认是不能提交一个空的提交信息,如果当前的文档没有什么修改,那么就是不能提交的,但是加上了这一行信息之后就可以提交了
-am
:分为2个参数-a
表示自动暂存所有所有已经跟踪的文件的更改
在git status之后
显示以下信息:
zzhi@zzhi:~/NEMU2021$ git status On branch master Your branch is ahead of 'origin/master' by 6 commits. (use "git push" to publish your local commits)nothing to commit, working tree clean
这句话是 Git 命令
git status
输出,用于显示当前分支的状态。它提供了有关当前分支和远程分支的同步状态的信息。具体的含义如下:
On branch master
:
- 你当前所在的分支是
master
。这表示你正在master
分支上工作。Your branch is ahead of 'origin/master' by 6 commits
:
- 你的本地
master
分支比远程origin/master
分支领先 6 个提交。也就是说,你在本地master
分支上有 6 个提交,这些提交还没有推送到远程仓库的master
分支。- 这些提交可能是在本地进行了新的工作或修改,而这些修改尚未同步到远程仓库。
(use "git push" to publish your local commits)
:
- 你可以使用
git push
命令将本地master
分支上的提交推送到远程仓库,以使远程的master
分支也包含这些提交。- 这条提示建议你使用
git push
将本地的更改更新到远程仓库,以保持远程仓库的内容与本地同步
在 Git 中,分支是平行的,没有严格的“分支下有分支”的结构。每个分支都是独立的,并且都从某一个提交(commit)开始,可以从任意其他分支派生出来。
平行分支
- 概念:当你创建一个新分支时,它相对于其他分支是平行的。所有分支都是平行的,可以独立发展。Git 以分布式方式工作,每个分支都有自己独立的提交历史。
- 操作:你可以在任意一个分支上创建一个新的分支,并且新分支和源分支是平行的,它们可以各自进行独立的开发,直到你选择将它们合并。
创建新分支的示例
假设你有一个
master
分支,并从它创建了两个新的分支feature-A
和feature-B
:git checkout -b feature-A master git checkout -b feature-B master
在这个例子中,
feature-A
和feature-B
都是从master
分支派生出来的,但是它们彼此是平行的,互不影响。分支的独立性
每个分支都可以有自己的提交历史,可以从不同的点开始。即使它们是从同一个起点(比如
master
)分出来的,一旦开始开发,两个分支的内容就会逐渐不同。你可以在需要时将这些分支合并到一起,也可以将一个分支重新派生出新的分支。分支结构的灵活性
Git 的分支模型非常灵活,你可以随时从任何分支创建新分支。即使从某个分支上创建了新分支,它们依然是平行的,而不是嵌套的。
示例:从
feature-A
创建feature-A1
你可以在
feature-A
上再创建一个新分支feature-A1
:git checkout -b feature-A1 feature-A
尽管
feature-A1
是从feature-A
分出来的,但它依然是平行的。这意味着你可以独立地操作feature-A
和feature-A1
,它们的关系仅仅是feature-A1
继承了feature-A
的历史。总结
Git 中的分支都是平行的,彼此之间没有严格的层级结构。你可以从任何分支派生出新的分支,Git 会记录这些分支的共同历史,但从逻辑结构上,它们都是平行的,不存在“分支下有分支”的层级关系。
要将 Git 库的一个分支上传到云端(远程仓库)的另一个分支,可以按照以下步骤进行:
1. 确保分支最新
确保你要上传的分支是最新的,拉取最新的更改:
git checkout 你想要上传的本地分支名 git pull origin 本地分支名
例如,如果你要上传的是
feature-branch
:git checkout feature-branch git pull origin feature-branch
2. 推送到远程的另一个分支
使用
git push
命令将当前分支推送到远程仓库的另一个分支。你可以通过以下命令实现:git push origin 本地分支名:远程分支名
例如,如果你想将本地的
feature-branch
分支推送到远程的another-branch
分支,可以使用:git push origin feature-branch:another-branch
这个命令的意思是:将本地的
feature-branch
分支的内容推送到远程仓库的another-branch
分支。如果another-branch
不存在,Git 会在远程仓库中创建它。3. 检查推送结果
你可以通过以下命令查看远程分支的状态,确保推送成功:
git branch -r
这将列出所有远程仓库的分支,你应该可以看到
another-branch
已经存在。4. (可选)设置远程跟踪分支
如果你希望在将来继续从本地的
feature-branch
推送到远程的another-branch
,可以设置远程跟踪分支:git branch --set-upstream-to=origin/another-branch feature-branch
这样,在未来推送时,你只需运行
git push
,而无需每次都指定远程分支。总结
以上步骤将帮助你将一个本地分支的内容上传到远程仓库的另一个分支。如果远程分支不存在,Git 会自动创建它。这个方法适用于将代码从一个分支迁移到另一个分支,或在不同分支之间进行同步。
NEMU概述
对于一般的应用程序而言,假如没有虚拟机的参与,则是操作系统直接运行在计算机硬件上,对计算机底层的硬件进行了抽象,向上为用户的程序提供了接口和服务。当运行这些应用程序的时候就需要使用这些接口
总的来说:程序不是直接运行在硬件系统之上的,而是在操作系统之上
对于虚拟机nemu来说,nemu是运行在机器操作系统之上的软件,它模拟了虚拟的计算机硬件。
红白机游戏是比较特殊的存在,在红白机之中是直接运行在红白机硬件上的,在nemu中,nemu只是模拟了一个硬件系统,本身在这个虚拟的硬件系统再没有更多的操作系统,红白机游戏就是直接运行在这个nemu模拟出来的硬件系统之上的
关于实现
把计算机看做成为一个由若干的硬件部件组成的,每一个硬件部件都是由一个c语言的数据对象来模拟,
其实就只是某种数据结构,仅仅是模拟硬件的话感觉并不会很难,感觉只是传统的大模拟
阅读源代码
对于计算机硬件系统模拟的主体就只是在nemu目录中
首先关于这一张图片,因为上学期的计算机系统基础说实话学的一点都不好,一定会回来补的(!!!!!
4个关键部分:设备device、储存管理memory management、main cpu、monitor
配置了一下ctags之后感觉vim要比vscode好用了
可以在函数和变量之间跳转,这样就能看到每一步分别是怎么样子的,感觉好好用
part 2
碎碎念:
从网站上找到了可能是nju的版本的操作手册,不得不说感觉是要比自己学校提供的改过部分东西的手册要精彩一些,不管是谁的手册,在看这些的时候总是会觉得要更有动力些
现在忙碌于想要找到Assert的用法,但是忘记了在手册的哪个地方了,想起来再acm中反复输入输出找bug的经历,感觉怎样的函数真的很重要,可惜当时没有记录下来
找到了,这次要好好记录
感觉很有趣啊,想要自己写些东西去记录博客,但是因为苦于感觉发现一些东西就去记录就会感觉很吃力,感觉还是会断了思路,因为一种不专心的愧疚感让我决定还是在完成一部分之后再进行记录,但是那样的手册中提到:
虽然不是我的学长学姐,但是我也有因为没有记录好在acm的每一天,让我觉得有些懊悔,多半想要继续打下去也有这方面的原因,不太好说,我会喜欢这些东西.
我甚至都没有听闻过这些东西,人和人的差距为什么会这样大?只是可能再怎么样努力也不会最终能进入这些学校,得考研么?还是会觉得有些担心失败,如果即便能保研也只有自己的本校吧,还是有些不甘心。绝对要做的,目标是能补齐没学会的系统知识能完成这样的系统。有更多的目标的,早就痛苦过,也不仅仅是学习之类的事情。
我受不了了,为什么,为什么给我的手册里面没有这些话,很痛苦。
凭什么?感觉到更能理解那人的心情了,可能也不是那样,但是也有知道些。
比较了一下两个手册,我不知道哪个才是正确的原版本,但是已经有很强的自卑的心情了。
在Assert中的第一个参数是,表示一个判断的条件,第二个参数实际上是一种输出的模式,表示如果返回值是false就是如果没有符合这样的条件,就把这个提示信息输出出来,其中的代码很有趣,可以改变字体的颜色。
实现递归解决运算问题,看到些说“分治可能没有听过”的时候还是有些骄傲,虽然实力也不怎么样,但是自己用的还是清清楚楚,别的不说,这些还比较基础的程序设计还是难不到自己。这样节省下来的时间需要去研究更多的东西才行。
我怎么找不到要在哪里使用这些函数,哪里使用make_token?
原来已经有todo告诉我相关的位置了
也有看过博客讲解的实验,震惊在为什么什么都那样轻松,但是我真的为了搞明白花了很久很久,也没有办法欺骗说因为自己研究的更多,于是会花更多的时间,这样的说法是没有道理的猜测,很无聊。
在这里有一个panic是无条件的断言,意思是请实现我,但是我既然要实现这样一条了就应该直接把它给删除掉,还是温柔些注释掉吧。
话说根据kiss法则搞定的这个函数有点懒没有去看看assert是不是就直接断开了,但是因为exper函数中有一个判断是不是成功的遇见,那么就也返回一个false吧。
对c的使用不多,我也不知道要如何定义到字符串的末尾,有点。。。。。等等,根本不需要字符串,已经提取出token了的。。
先想一下对于这样的eval函数的实现方法在回去对照一下思路:
对于每一个拆取出的小式子都需要找到一个恰好我知道可以分开的token的位置然后再继续递归,也就是说每个都需要一次遍历
哎呀,如果能用栈就好了,不知道c有没有这样的数据结构。有点怕内存会超,直接用数字记录就好了
我每次都是从一个token去往下拆分,所以关于运算符号的问题其实好解决,然后因为我想要拆分+和-或许我把type改成一个数字会好写一点,只要去判断是不是大于或者小于某个数字就好了
这样的话需要返回的值还是很好写,代码的实现这种还是一种灵光一现的感觉,操作手册的可能还不需要看,但是其中给出的特判的括号还是很有参考价值,这样就不用再去debug了,比较好
对,我的nr_token用的是nr_token++,所以传参要-1.不然又要陷入难以解决的bug里面了
我发现一个很不好的弊端,为什么拆出来的token如果是一个数字还要存放在一个数组里面,搞的我很难办,因为我想要把数字提取出来,但是我不知道数字有几位,我需要去修改那个maketoken去加入一个标识符,还不能缓存溢出,明明可以一下子完成的事情分了好多步,我都想把那个str数组给删除了。。。。
好像可以尝试一下?直接全注释掉重新写一次,别管,不出bug就是好代码,嘻嘻
回去查一遍发现*号放在里面了,差点有要找好久的
加了一个参数舒服多了,也没有注释,因为可能那样的str在别的地方会有用么?我不太知道,但是我就是重新加入了一个num放进了结构体里面,其实这样的话,负数的问题也都一起顺带解决了?
这里查括号的地方,突然感觉从后往前查才是正确的选择,因为这样的话就可以直接就把分割点的token给找出来了
但是我的实现的方法和手册中的不一样,可能我不会出错,不会需要哪些特别的判断,我只需要特判一下2个端点的样子就可以了
是这样的,我想要直接就找到正确的分隔点,然后因为可能分隔出的式子是完全罩在一个括号里面的,所以这样的分隔点就再括号里面,这样的话就需要去重新决定一下判断出断点的cnt的条件,或者去改变一下开始枚举的位置,我觉得会不会出现如下的情况:(((((num)))))
很让人无语,但是没有错。所以需要一个循环去提取出来,所以要从两遍一起往内部去缩
但是去提取出这样一个+或者-
万一没有怎么办?
就需要找到最开始的一个运算符,那就给一个确定的标识,如果是这样的标识,说明没有找到+-就更新给第一个运算符
-1是一个好数
我现在觉得自己强的可怕!!!这么恐怖的情绪的转化我也是个神人,等年纪大了绝对是一个神经病。。
完成!
小跑一下。先看看在哪里调用的
???怎么调用都要自己写啊???
完了,这些debug要de麻了
最后再负数吧。wwwww
竟然是再讲颜色!!!!之后回来学。
其实还好,只要自己开一个c文件自己敲代码使用就可以了
但是还是很烦,我不会写,因为有很多函数,只能自己在nemu 里面实现一个计算器了
好烦要仔细思考了,还需要写一个函数去判断算式是不是合法,文档里面没说但是++i的也是合法的,这样要再多写一些函数,也是其实直接写一个c也不麻烦
不能再虚拟机里面写,我不会写makefile,这样就不对了,我也不会配置环境,还是要到自己的机器里面写ww
不是啊,在nemu里面定义一个p的指令就好了。。。
nr_token的值一直是步长为2的跳,但是我找不出毛病,可能是在那个地方会有自增的1?
为什么数字地方加2次?
多写了一次++。。。
我改了什么东西,突然就不能编译了?
e+position 之后指向的是当前的下一个位置,所以应该用substr——start
发现括号的判断也出现了一些失误,但是现在就可以了。接下来基本的运算其实是可以的,完成其他的任务,
突然发现在vscode里面ctrl + 点击,就可以直接和ctags一样的效果了,好吧,终端的作用就只有make 了
vscode始终是神啊
发现自己的手册中还涉及到更多的内容和任务,感觉更像是互补的感觉,先前的很多感受现在没有了
要写复杂的实现了
感觉不能太着急了,要有完备的思路在写,在记录
ps:要注意负数的乘除怎么办,去调整一下有符号数和无符号数
注释太多了会有些乱,要删除一些
还有一个判断式子会不会合法的函数还没有实现,之后有时间要补一下,虽然不需要,但是是很朴素的注意细节的实现
字符串如果填充数组的时候会填不满,用\0补位就是一个完整的字符串了
去完成监视点的使用:
实际上就是一个链式前向星,然后我都忘记是如何实现的了,想一想。
但这个是链表,实际上会比链式前向星要简单很多
ok,这个初始化说实话我不是很熟悉链表,但是更多的是因为这个初始化我没有看懂,现在是很明确的事情,这样就会比较好
part 3
很怪,为什么会突然出现一个0???
并且只有在前面那个输出的式子之后才有这个东西???
x 10 0x1234
p 0xc0100000 - ($edx+0x1234-10)*16/4
p (!($ecx!=0x00008000)&&($eax ==0x00000000))+0x12345678
p -5+*($eip)
w ($eip==0x100224)
c
不太知道原因,但是怀疑是有符号数和无符号数混用的结果
改一次试试
找不到原因,就直接改变要读取几个,因为看到正则表达式识别是正确的,不知道为什么会错。感觉上可能是因为它原先是一个数字,导致末尾有0,然后复制的时候那个0还在哪里,但是会还觉得不对,因为有改过\0,可能是顺序的问题么???还不知道,找时间看
想要恢复就是把比较的n删除就好了
为什么所有的都是优先级全是5 啊???
可能是没更新我感觉,毕竟记得我写的是min
??这个不用更新啊
老毛病,switch后面没有break
优先级的问题解决的
但是还是比较奇怪,因为每个后面都有break,但是没有作用到switch上
得数也不对
得数不对的原因应该是16进制的算式没有正确的转化成为负数