首页 > 编程语言 >nand2tetris_hack汇编语言

nand2tetris_hack汇编语言

时间:2024-04-05 23:55:25浏览次数:35  
标签:计算机 汇编语言 代码 寄存器 指令 指令集 hack nand2tetris

计算机

我接触的第一台电脑是winXP系统,我拥有的第一台电脑是win7,也就说一开始我理解的计算机就有着好看的界面,灵活的操作性方式,拥有许多软件,可以做很多事情。
我们可曾想过,大部分机器都有其专属用途,比如榨汁机只能用来榨汁、削皮刀只能用来削皮,而计算机,他可以播放视频、浏览网页等等,这是一件多么神奇的事情!那这是如何做到的
开始的理论模型图灵机,至后来真正实现了的计算机基础架构冯洛伊曼体系。历史不去追溯,我们看一下,这门课程将要实现的计算机基本架构图

图中省略了总线和控制单元,大体思路是程序和数据放在内存中的两块,ALU通过从内存和寄存器中取值完成运算,输出至外部设备或内存和寄存器中。看起来不难是吧,可是第一步怎么做

指令集

可以发现,此刻我们对组装的计算机并没有一个具象化的概念。他需要实现哪些功能,他的内部数据如何传输等等,我们一无所知。课程老师在这一节,先假定我们已拥有了这样一个hack计算机,我们学习hack-CPU提供的指令集,进行简单程序开发。这样在实现CPU之前,我们大概知道了我们想做的是什么
计算机中,用户输入的指令,将会被编译器翻译为二进制编码(后面需要实现的),继而交给CPU执行。指令需要实现的功能有三

  1. 指令需要计算机要做什么,比如取数还是运算
  2. 指令需要能够控制硬件的执行,比如正常指令都是逐行执行的,有时需要跳转
  3. 指令需要告诉硬件如何做,比如去哪里取值,输出放在哪里
    实现指令集的过程中,存在硬件和软件之间的权衡。这门课里就没有在指令集层次支持乘法,但是我们通过软件算法实现。所以,硬件设计和机器语言往往是同步进行的

hack汇编

介绍课程hack汇编语法之前,先引入几段大众认知的标准汇编语言

我的前几篇博客里,简单的介绍了如何编写8086汇编代码。相比于高级语言里复杂的语法,汇编语言更接近编程的实质,只提供基础的算数运算和逻辑运算。写汇编代码其实很受限,脑子里只能有加加减减、选址赋值这些操作,不过课程老师也说了,“simple people are impressed by sophisticated thing, sophisticated people are impressed by simple thing”

hack计算机内存和寄存器架构

在通用计算机中,代码其实也是数据,只是我们将他放在了代码段内,这里hack计算机为了简便处理,不在一整块内存上划分代码与数据,而是设计了两块内存,分别存放代码和数据
hack计算机有两个寄存器,存放地址的A寄存器和存放数据的D寄存器。我们可以设置A寄存器的值,去内存中取值,然后将值保存在D寄存器中,同时提供了一个变量M,M代表此刻数据区选中的值,可以对他进行赋值和运算

hack计算机指令集

有了内存和寄存器存放数据/代码之后,此时需要一套指令来读取/写入数据,并交给CPU运算。hack计算机提供了两种指令集,依据指令集编写而成的代码被加载入ROM中,而后逐行执行;至于指令怎么被加载,ROM又是如何执行的,暂且先不讨论。现在可以理解就是有了这样一个hack计算机,提供了这样的指令集,请为他编写代码。其实这和我们学一门新的语言一样,学语法,写功能,再去了解其本质

A指令集

这个比较简单A-address取址,并自动赋值A寄存器;至于图中提示的如何确认,随后而来的取值是到数据区还是代码区,这是后面实现CPU时考虑的事情

C指令集

这个略复杂些,分为了以下几种情况

  1. A/D/M可以赋值立即数(常数),不过可选值只有0,-1,1三种
  2. A/D/M可以互相赋值,支持相反数
  3. A/D/M支持+-算数运算,也支持&|逻辑运算,特别的支持立即数1,可以理解为第二种情况的扩展
  4. 跳转指令,课程选择了在下文介绍,用于控制程序执行流程

    如果现在和你说hack计算机就是由这两种指令集做为基石搭建而成,你肯定不相信。其实两种指令集配合起来使用,可以实现对任何一个内存单元的取值和赋值,看例子会很容易理解了
    这里直接将A寄存器当作立即数来使用了

    这里是通过M这个变量,方便的实现内存地址赋值操作,并总结了一种基础范式,A指令取值,C指令赋值

    来一个稍难一点的例子,这里可以实际去CPU模拟器中执行,看一看内存和寄存器在执行过程中,值的变化

hack计算机 Symbolic programming

标题我不知道怎么翻译,实际这里是介绍了使用一些人类可读的方式来影响程序执行

分支

高级语言里的if else以及for循环,需要通过这种方式实现,不知道为什么,习惯了前几节使用选择器来判断,感觉这种jump方式,也不是那么难受了。跳转指令实际上是包含在C指令集内的,下文会再对C指令集综述

再贴一个稍微复杂一点的,一般是这样配合使用的

变量

之前在介绍A指令集的时候,@x 这里x可以用来表示立即数,也可以用来表示实际内存地址,当混在一起的时候,就看不懂这里x是代表什么的了;所以我们需要一种区分,约定,如果这里是表示实际内存地址的,我们可以使用一个小写英文来代替,相当于高级语言里申请了一个变量,内存地址自动从16号开始,前面被内置变量名R0..R15占据了

这有一个立即数和实际内存地址混合使用的例子,很容易区分这两者

标签

这个主要是为了配合跳转指令来使用的,毕竟跳转的时候还要数在第几行,修改代码之后都要调整一下受影响的跳转代码,这也太痛苦了

实战

这里主要介绍了一种思路,编写汇编代码时,先尝试思考伪代码,再将伪代码翻译为汇编语言。执行时汇编器再翻译为机器指令,可以发现变量和标签这些语法糖都被抹去了

这里提到了一个问题,因为计算机通电之后是不会停止的(这里我不明白CPU占有率是怎么一回事),程序会一直往下执行的。就像C语言里的数组越界,我们需要这个程序执行结束之后,“停”在最后位置

顺便说一句,上面的代码可以这样优化。我在平时写代码,也会尽量写if 不写else

hack计算机低级编程

迭代

指针

实战

其实学到这里,基本已经把计算机程序里的三种结构理解了,大部分的功能都可以参考于此

hack计算机指令集-补充

标题有点奇怪,主要开始的时候如果介绍完整,很难解释,现在学习了这么多例子,已经对hack汇编语言有了完整的认识,再来谈一谈指令集

A指令集的两种用法

C指令集的完整概述

这里贴两张图感受一些,C指令集的组成规则

稍复杂些的跳转指令,也被容纳在内了,是不是有种统一美

注意事项

这里的意思是,不要混用jump指令和M赋值,因为二者都依赖A指令

输入与输出

这里hack计算机内置了显示器和键盘芯片,并将他们映射到内存的某一块区域;可以通过读取/写入这一块区域内的值,来显示内容或读取当前正在操作的键值

显示器

@SCREEN为内置变量

可以将一个16位数设置为-1,快速设置一大块像素点为黑色

键盘

键盘简单一点,这里的值来自于被按下键的Unicode编码值,没有键被按下时,0

使用时,也内置了一个变量@KBD

课程作业

这节课程的基础知识到这里就结束了,留下了两个作业,贴一下代码加深理解

实现乘法

这里实现的很简单,简单的++,而且没有判断R0和R1谁大谁小寻找更少的迭代次数

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/4/Mult.asm

// Multiplies R0 and R1 and stores the result in R2.
// (R0, R1, R2 refer to RAM[0], RAM[1], and RAM[2], respectively.)
// The algorithm is based on repetitive addition.

@R2
M=0

@R0
D=M
@END
D;JEQ
@R1
D=M
@END
D;JEQ

@i
M=0
(LOOP)
    @i
    D=M
    @R1
    D=D-M
    @END
    D;JEQ

    @R0
    D=M
    @R2
    M=M+D
    @i
    M=M+1
    @LOOP
    0;JMP

(END)
    @END
    0;JMP

白屏/黑屏

这个程序里就能看出hack计算机的局限性了,因为只有两个寄存器,想把黑屏和白屏代码封装起来,就很有难度了。最后是黑屏写了一套代码,白屏写了一套代码,二者就在大循环里跑,也没有设置子循环,让程序完成渲染后处于监听键盘的状态。不过,至多就是按键的时间长一点就好了..

// Runs an infinite loop that listens to the keyboard input. 
// When a key is pressed (any key), the program blackens the screen,
// i.e. writes "black" in every pixel. When no key is pressed, 
// the screen should be cleared.

(MAIN)
    @KBD
    D=M
    @BLACK
    D;JNE

    @WHITE
    0;JMP

    @MAIN
    0;JMP

(BLACK)
    @i
    M=0
    @j
    M=0
    @head
    M=0


    (BLACK-LOOP1)
        @i
        D=M
        @255
        D=D-A
        @MAIN
        D;JGT
    
        @j
        M=0
        (BLACK-LOOP2)
            @j
            D=M
            @31
            D=D-A
            @BLACK-LOOP1-END
            D;JGT

            @head
            D=M
            @j
            D=D+M
            @SCREEN
            A=A+D
            M=-1

            @j
            M=M+1
            @BLACK-LOOP2
            0;JMP

        (BLACK-LOOP1-END)
        @32
        D=A
        @head
        M=M+D
        @i
        M=M+1
        @BLACK-LOOP1
        0;JMP

(WHITE)
    ...
    M=0
    ...

(END)
    @END
    0;JMP

总结

这一节贴了好多图,不过想想还是很有成就感的,我在学会一门语言之后,还可以把他表述出来。这节看懂了课程上的例子之后,难度就不大了,最后的白屏/黑屏作业也只是复杂,而不是困难。期待下节课的CPU实现!!

标签:计算机,汇编语言,代码,寄存器,指令,指令集,hack,nand2tetris
From: https://www.cnblogs.com/snowsteps/p/18115678

相关文章

  • PHP 一句话木马 @eval($_POST[‘hack‘]);作用解释
    简介:@eval()函数的作用是,不将错误爆出来,且将变量中的内容当作php的代码,进行执行,任意代码均可,所有能直接控制主机。转自:https://blog.csdn.net/BYZY1314/article/details/127792228一句话木马如下,利用文件上传漏洞,往目标网站上传该木马,即可获取和控制整个网站主机目录<?php@......
  • tryhackme-Boiler CTF
    信息收集使用nmap对靶机进行信息收集根据扫描开放的端口,先访问21端口进行初步探测并没有得到有用的提示,继续访问80端口进行探测根据页面回显,靶机应该是一个ubuntu的操作系统,可能有隐藏目录,使用gobuster进行目录扫描gobusterdir-uhttp://10.10.229.228/-w/usr/share/......
  • google_hacking_study
    简单了解一下GoogleHacking语法。这是goolehacking十个基本语法。""完全匹配据说匹配比较精准,但是我不加引号好像也没什么区别耶*模糊匹配、?表示单个字符,用通配符时要将引号将关键词括起来*.exe+逻辑与用了加号,那多个关键词都会出现在搜索结果的摘要中。gpt:GoogleHa......
  • 今早,这个中国人做的开源项目被YC的hacker news收录了!
    众所周知,YC在创业者心中的地位,它孕育出了openai、airbnb等众多硅谷知名企业。就在今早,YC的hackernews把这个由中国人做的开源项目收录了!这是一个什么项目?先上开源地址:https://github.com/saasfly/saasfly简介中可以看出,这是一个具备足够创新的“下一代SaaS模版”,旨在帮助使......
  • <汇编语言> 3. 寄存器(内存) | 检测点 3.2
    (1)补全下面的程序,使其可以将10000H1000FH中的8个字,逆序复制到20000H2000FH中。逆序复制的含义如图3.17(P70)所示(图中内存里的数据均为假设)。movax,1000Hmovdx,ax//栈段为1000:00H~1000:0FH_pushax,1000H___PUSHss,ax_____//栈顶指针为0FH+1=10H_pushsp,00......
  • nand2tetris_ALU
    这一节,我们将尝试构建CPU中的ALU单元。明明上一节才开始学习基本逻辑门,这一节就实现ALU,当时的我是吃惊的,但确实仅用逻辑门就可以完成。在开始逐步实现之前,先补充一些前置知识前置知识HDL上一节构建选择器时,得到了一个较长的函数式,那么如何验证函数表达式呢。课程老师提供了用......
  • AMD hipcc 生成各个gpu 微架构汇编语言代码的方法示例
    1,gpuvectorAdd示例为了简化逻辑,故假设vector的size与运行配置的thread个熟正好一样多,比如都是512之类的.1.1源码vectorAdd.hip#include<stdio.h>#include<hip/hip_runtime.h>__global__voidvectorAdd(constfloat*A,constfloat*B,float*C){inti=......
  • win靶场练习where-1s-tHe-Hacker
    第一题题目说被攻击力,那就去网页看看怎么个事第一题秒了第二题 问修改时间,那就看php文件最后修改时间即可第三,四,五题 找webshell,d盾扫一下第六题 第七题 win+rcmdnetuseradmin$第八题 win+r eventvwr.msc安全筛选时间常见id类型4624登录成功......
  • 汇编语言 分数段
    汇编语言设有一个数组存放学生的成绩(0100),编制一个子程序统计059分,60~69分,70~79分,80~89分,90~100分的人数,并分别存放到scoreE,scoreD,scoreC,scoreB,scoreA单元中,编写一~个主程序与之配合使用。源程序:stacksegmentstack dw512dup(?)stackendsdatasegment score......
  • Devvortex Hack the box
    nmap-A-oNinitial_scan10.10.11.242发现打开了80和22用dirsearch和fuff扫子域名和子目录直接发现目录/administrator进去发现是Joomla页面发现版本是4,那么就和漏洞Joomla(CVE-2023-23752)一样可以看https://xz.aliyun.com/t/12175?time__1311=mqmhD5DK7IejhDBdPx2DUEF......