Process 如何使程序与硬件设备协同工作

Process 如何使程序与硬件设备协同工作,process,hardware,Process,Hardware,我想知道一个程序如何与硬件设备一起工作。我想知道的是基础知识,而不是深奥的知识 所有编程代码都有以下内容 变量如int、float、short等 函数和函数调用 如if-else等语句 计算 像for循环之类的循环 我想在我们编程下载到硬件时,将数据传输到编程存储器(ROM)。当我们运行程序时,上面提到的所有东西都进入RAM,还是只进入特定区域,比如功能数据 当我们考虑8位总线时,由于总线很小,所以像8位字符那样的8位数据如何? 什么是堆栈以及如何使用它编程 为什么void main功能很重

我想知道一个程序如何与硬件设备一起工作。我想知道的是基础知识,而不是深奥的知识

所有编程代码都有以下内容

  • 变量如int、float、short等
  • 函数和函数调用
  • 如if-else等语句
  • 计算
  • 像for循环之类的循环
我想在我们编程下载到硬件时,将数据传输到编程存储器(ROM)。当我们运行程序时,上面提到的所有东西都进入RAM,还是只进入特定区域,比如功能数据

当我们考虑8位总线时,由于总线很小,所以像8位字符那样的8位数据如何? 什么是堆栈以及如何使用它编程

为什么
void main
功能很重要?如何识别它


请告诉我如何使用硬件来运行程序的基本概念

正如@nos所说,解释它需要大量的书籍

代码和硬件之间缺少的是编译器。它的作用是将代码(C、C++或任何语言)翻译成汇编。汇编大致上是一组CPU或微控制器能够理解的非常低级别的指令

当程序被翻译成汇编时,它被上传到内存中。根据体系结构的不同,它可以是通用内存(冯·诺依曼)或程序内存(与哈佛体系结构的数据内存相反)

当谈到堆栈时,您还可以使用指针。指针指向(是的,一个指向堆栈“级别”的指针。例如,您有指向当前指令的“当前”指针。当前指令完成后,指针将递增,因此指向下一级。 当调用子函数并指向停止父函数的级别时,将使用另一个指针。子功能完成后,返回到停止的位置

这些指针存储在寄存器中,寄存器是芯片中的小型(快速)存储器

至于主功能,硬件在编译时不会随意识别它。对于硬件,只有一个要执行的程序(即main)和对子函数(即main中使用的函数)的调用

所以。。当你编写一些代码时,让我们用C:

int main ()
{
    int a = 0;
    printf("a = %d", a);
    return 0;
}
main的内容被翻译成汇编,是您的“正常”程序。首先,它将0放入寄存器的一个单元格中。然后它将其置于挂起状态以执行printf(它使用保存0的单元格中的值),并将其停止的位置保存在指针中。完成后,当前指针会将保存的指针的值取回并继续

关于ram中的内容:内存级别不同。硬盘或固态硬盘,速度慢但体积大,价格便宜。Ram,速度更快,但更方便,体积更小。缓存,内置于CPU中,速度非常快,体积更小,成本更高。寄存器也是内置的,速度更快但更小。当CPU使用变量时,它进入寄存器。但是现代CPU“猜测”(也称为预取)在不久的将来可能需要什么变量(例如,您读取表的前两个单元格,它可能会在您请求之前加载第三个单元格),并将其放入缓存中。否则,它在ram中


希望这会有所帮助,可能会有一些捷径或不准确之处,但这就是它的大致工作原理。同样,很难用几行字来概括上百页的内容。

这里有很多问题。 首先,让我们假设一个简单的情况,比如Arduino,它是软件和硬件的组合。 软件部分从编写一些简单的C++代码开始,例如:

byte ledPin = 13;
void setup(){
pinMode (ledPin, OUTPUT);
}
void loop(){
digitalWrite (ledPin, HIGH);
digitalWrite (ledPin, LOW);
}
接下来,您将编译代码。Arduino IDE(集成开发环境)做了一些事情(在后台,比如添加一个main()调用setup() 函数一次,循环()函数重复,将C++转换成汇编代码,它看起来可能是这样的(不是上面的实际输出):

这不是真实的数据。0001000可能是ROM中的起始地址,接下来的32个字符是要编程的16字节数据,最后4个字符可能是通过某种方式操纵数据创建的校验和。程序员接收数据,执行相同的操作,如果校验和正确,它会将数据烧录到内存中

十六进制代码可以通过几种方式放入ROM中-程序员可以控制芯片并直接将代码放入内存,复位后芯片将只运行代码;,或者,在复位后,引导加载程序可以从芯片上的ROM区域运行,它将通过串行线(Rx、Tx)与PC对话以接收数据,然后将数据写入另一个ROM区域。如果引导加载代码没有检测到PC试图与它对话,它将跳转到代码开始的ROM地址并从那里运行

8位微控制器可能有一些16位寄存器,它可以用于捕获ADC转换的结果,或者它可以将结果存储为两个8位字节,具有高和低数据

堆栈可能是专用硬件寄存器,也可能是SRAM的一个区域,用于保存数学运算的结果。代码负责将内容放在堆栈上并将其读回,您通常不会对其进行编程。对于'328P,有2048个字节的SRAM,因此您只需确保代码中声明的变量(如byte ledPin=13;)不太多,因为这些变量会耗尽所有内存,也不会为代码留出空间。例如,在328Ps中,这通常是由于尝试访问超出其限制的数组而导致的,因此要么返回无意义的结果,要么在写入超过数组末尾时重写其他内容而导致程序崩溃。C++的灵活性很强,但如果不小心,也会让你陷入麻烦。
; Define pull-ups and set outputs high
; Define directions for port pins
ldi r16,(1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0)
ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0)
out PORTB,r16
out DDRB,r17
; Insert nop for synchronization
nop
; Read port pins
in r16,PINB
000100005673495a6b4f5e205673495a6b4f5e24465