首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么只有当我存储和加载这些寄存器时,Printf才能工作?aarch64

在aarch64架构中,寄存器是用来存储和处理数据的重要组成部分。Printf函数是用来输出信息到终端或文件的函数。当你存储和加载这些寄存器时,意味着你在程序中使用了这些寄存器来存储Printf函数所需的参数和相关数据。只有在正确地存储和加载这些寄存器后,Printf函数才能正常工作。

在aarch64架构中,函数调用时,参数和局部变量通常存储在寄存器中。Printf函数需要一些参数,例如要输出的字符串以及可能的格式化参数。这些参数需要存储在特定的寄存器中,以便Printf函数能够正确地读取并进行处理。

另外,Printf函数还需要将输出的结果写入到终端或文件中。这也需要通过寄存器来传递相关的信息,以便正确地将结果输出。

总结起来,只有当你正确地存储和加载这些寄存器时,Printf函数才能够获取到正确的参数和相关数据,并将结果正确地输出到终端或文件中。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云计算服务:https://cloud.tencent.com/product
  • 腾讯云对象存储(COS):https://cloud.tencent.com/product/cos
  • 腾讯云云服务器(CVM):https://cloud.tencent.com/product/cvm
  • 腾讯云容器服务(TKE):https://cloud.tencent.com/product/tke
  • 腾讯云数据库(TencentDB):https://cloud.tencent.com/product/cdb
  • 腾讯云人工智能(AI):https://cloud.tencent.com/product/ai
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Linux】进程切换&&环境变量

(2) 计算机调度某个进程,CPU 会把这个进程的 PCB 地址加载到某个寄存器,也就是说,CPU内有寄存器可以只找到进程的PCB地址。...(4) 当进程在运行的时候,一定会产生非常多的临时数据,这些临时数据只属于当前进程,虽然CPU内部只有一套寄存器硬件,但是寄存器里面保存的数据是属于当前进程的,寄存器硬件寄存器内的数据是两码事。...退出,然后再次登录,系统会再次加载环境变量。 四.环境变量相关的命令 1.echo +变量名:查询某个环境变量,如:echo PATH查询PATH环境的内容。...} 上面这段代码,只有用root的身份才能去执行,否则,就会权限不足。...只有这样,在做认证工作,就会得到通过,操作就会的到处执行。

14810
  • aarch64指令集_AArch64应用程序级编程模型

    PSTATE字段了在PE位于EL0使用AArch64访问保存AArch64状态的PSTATE字段的专用寄存器。...所有这些副作用,是有保证的:对执行流中较早的指令不可见。 对执行流中的后续指令可见。 System registers 系统寄存器为执行控制、状态一般系统配置提供支持。...只有在实现ARMv8.4-DIT才会实现这个位。 在重置为AArch64状态,该位设置为0。 为数据处理指令提供了独立的定时功能 PSTATE。说,CPSR。说字段。...所有加载存储都必须具有对加载存储的数据的值不敏感的定时。 ARM建议ARMv8.3指针身份验证指令的时间不依赖于指针身份验证中使用的键值,而与PSTATE.DIT无关。...然而,这些指令很可能具有在许多情况下数据不变的时序。 对应的DIT位被添加到AArch64状态的PSTATEAArch32状态的CPSR。

    71820

    将 Linux 移植到 M1 Mac 真的太难了!

    ARM64系统能够同时使用 UEFI 设备树进行引导,而且只有这样做,才能像 PC 那样通过 GRUB 等引导程序通用的流程安装升级内核。但是 m1n1 并不支持这样做,那么怎么办呢?...关键的数据必须保持在有电的电路中,或者移动到有电的备份存储中。正常情况下,这些指令不会导致可见的数据丢失,CPU 可能会丢弃一些不再需要的数据,但会保证不丢失软件正常工作所需的数据。...试想一下,如果我们必须追踪一个微妙的 GPU 挂起问题,而由于 AIC 驱动的竞争条件问题,这种问题只有在游戏中做某些事情才会发生(但只是偶尔会发生,并且需要一个小时才能重现)!...当我们说 AArch64 CPU 只有一个 IRQ 线的时候,我们并没有提及它的兄弟:FIQ 线。FIQ(Fast Interrupt Request,快速中断请求)是另一个中断机制。...相反,FIQ 处理代码必须依次检查每个 FIQ 源(检查每个源的方式都不一样,因为需要检查特定的设备寄存器),找出哪个需要关注,只有需要关注才将中断发给该设备的驱动。

    3K20

    AArch64 学习(一) 基础指令, 内存布局, 以及基础栈操作

    其实它 AArch32 被称为 “执行状态” (execution state), 那么我们可以说 ARMv8-A 同时支持 AArch32 AArch64 两种状态, 在 AArch64 状态下...我们为什么要了解这些? 指令集本质上定义了 CPU 提供的“接口”, 软件通过这些“接口”调用 CPU 硬件的能力来实现编程...., 可以是一个寄存器, 或者是常量值 不一定所有的制定规则都是这样的, 为了减少理解的成本, 我们先介绍几个简单却又必须的指令, 其他的指令会在后面用到时再做介绍. // X1 存储了一个地址, 把 X1...Stack frame 主要有两个基础用途, 一个是存储临时变量, 再者是函数调用传参. 后者会在后面的文章的讲述, 这里我们主要看一下在没有函数调用的情况下栈空间的使用...., #offset] 的方式 保存 数据到 栈空间 通过 ldr x寄存器, [sp, #offset] 的方式 加载栈空间 数据到 寄存器 6.

    2.4K30

    rt-thread 针对不同架构芯片移植的方法

    剩下的事情就是解决为什么没有达到预期效果的问题。...对于bss段清零的必要性是因为c语言的语法规则,以前的存储程序的存储器是很贵的,所以程序在生成的时候,把未初始化的全局变量和静态变量,这些存储空间不存入存储器空间,然后在程序加载的时候,将这段空间指向的区域清零...移植的工作难点 对于上面的步骤中,最难的就是栈帧的规划,上下文切换中断处理。 结合实际移植经验,往往容易出问题的地方就是入栈出栈的顺序对不上,或者有些寄存器没有存到栈中。...一般熟悉rt-thread的底层代码并不是很难,从头读一遍aarch64的rt-thread最小系统实现两三天就能差不多理解,而芯片手册的阅读要结合实际的工作经验,弄清楚芯片特权模式、看懂寄存器,看懂汇编基本就可以了...当然有些处理器是需要实现mmu才能正常执行的,比如aarch64,必须实现mmu的功能,即使是1:1映射。

    1.1K30

    深入理解计算机系统(1.1)------Hello World 是如何运行的

    所有计算机系统都有相似的硬件软件组件,它们执行着相似的功能,我们只有深入了解这些组件是如何工作的,以及这些组件是如何影响程序的正确性性能的,才能写出高质量的代码。...包括磁盘文件、存储器中的程序,存储器中存放的用户数据以及网络上传送的数据都是由一串位表示。而区分不同数据对象的唯一方法就是我们读到这些对象的上下文。...CPU 在指令的要求下会做如下操作:     ①、加载:把一个字节或者一个字从主存复制到寄存器,以覆盖寄存器原来的内容     ②、存储:把一个字节或者一个字从寄存器复制到主存的某个位置,以覆盖这个位置上原来的内容...如果该命令行的第一个单词不是一个内置的外壳命令,那么外壳就会假设这是一个可执行文件的名字,它将加载并运行这个文件。   初始,外壳程序执行它的指令,等待我们输入一个命令。当我们在键盘上输入字符串"..../hello"后,外壳程序将字符逐一读入到寄存器中,再把它放入到存储器中,如下图:   PS:为什么要输入“./hello”来执行,对于Linux系统有一定了解的人,可能知道这是运行命令的一种方法。

    1.8K90

    深入理解Aarch64的内存管理

    这种转换需求也适用于缓存数据,因为在 Armv6 更高版本的处理器上,数据缓存(DCACHE)使用物理地址(物理标记的地址)存储数据。因此,必须先翻译地址,然后才能完成高速缓存查找。...下图展示了多个物理地址空间的映射关系: 地址大小 AArch64 是 64 位架构,但这并不意味着所有地址都是 64 位的。虚拟地址以 64 位格式存储。...因此,加载指令 (LDR) 存储指令 (STR) 中的地址始终在由X 寄存器指定。但是,并非 X 寄存器中的所有地址都有效。...这类似于 ASID 为来自不同应用程序的在翻译工作的方式。实际上,这意味着某些转换将同时使用 VMID ASID 进行标记,并且两者都必须匹配才能使用 TLB entry。...只有在使用 64KB 颗粒才能使用完整的 52 位。 地址转换的初始level 虚拟地址空间的粒度大小共同控制地址转换的起始级别。

    1.4K20

    关于risc-v启动部分思考

    当我看完aarch64的芯片手册,再看risc-v的boot,设计思想竟然可以做一些对比,同样去看risc-vmips的寄存器,也可看到高度的一致性。...这些适配工作投入的精力难度恐怕是需要集结各国最强的研发实力才能发展完善的。而risc-v就有这个魔力,竟然可以一呼百应,大概是大家受到arm与因特尔的压迫已经很久了,大家都想自己造芯片玩玩。...FSBL(First Stage Boot Loader ):启动PLLs初始化DDR内存。 BBL(Berkeley Boot Loader ):提供加载,并且管理着二进制接口(SBI)。...使用的是BSD-2的开源协议,也就是任何人都可以随意修改使用,也提供了通用的规范化的接口实现。 这里就需要理解一下为什么需要规范化了。...5.openSBI call接口的实现 opensbi不仅仅具有加载引导功能,也能够供S-Mode的OS使用,比如提供串口控制台或者中断的分发等等。调用方式可以通过ecall来实现。

    3.8K21

    抛砖引玉-计算机系统

    C 库中的一个函数,printf 函数存在于一个名为 printf.o 的单独的预编译好了的目标文件中 结果得到 hello 文件,它是一个可执行目标文件,可以被加载到内存中,由系统执行 l 了解编译系统如何工作的益处...在任何时刻,PC 都指向主存中的某条机器语言指令(即含有该条指令的地址) CPU在指令的要求下可能会执行这些操作: l 加载:从主存复制一个字节或者一个字到寄存器,以覆盖寄存器原来的内容 l 存储:从寄存器复制一个字节或一个字到主存的某个位置.../hello” 后,shell程序将字符逐一读入寄存器,再把它存放到内存中。当我们在键盘上敲回车键,shell程序就知道我们已经结束了命令的输入。...,称为 高速缓存存储器,存放处理器近期可能会需要的信息 当shell加载运行hello程序时,以及hello程序输出自己消息,shellhello程序都没有直接访问键盘、显示器、磁盘或者主存。...进程则是对处理器、主存 I/O 设备的抽象表示 像hello这样的程序在运行时,操作系统会提供一种假象,就好像系统上只有这个程序在运行,这些假象是通过进程的概念来实现的 进程是操作系统对一个正在运行的程序的一种抽象

    21120

    新名词|什么是「电源」程序员?

    pritnf("hello, world\n"); return 0; } 这是用 C 语言输出的一个 Hello,world 程序,尽管它是一个非常简单的程序,但系统的每个部分都必须协同工作才能运行...区分不同数据对象的唯一方法是我们读取对象的上下文,比如,在不同的上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串或者机器指令。 为什么是 C 这里插播一则新闻,为什么我们要学 C 语言?...当我们在键盘上输入了 ./hello 这几个字符,shell 程序将字符逐一读入寄存器,再把它放到内存中,如下图所示 当我们在键盘上敲击回车键的时候,shell 程序就知道我们已经结束了命令的输入。...这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间,硬件会立刻执行必要的映射。...当程序引用到一部分不在物理内存中的地址空间,由操作系统负责将缺失的部分装入物理内存并重新执行失败的指令。 在某种意义上来说,虚拟地址是对基址寄存器变址寄存器的一种概述。

    32010

    【Linux】进程概念(上)

    一句话,所有设备都只能直接内存进行交互 为什么会有以上的规定呢?...但是我们可以多次执行结束一个进程,观察它的 pid ppid,如下图: 我们可以观察到,这个进程每次的 pid 都是不一样的,但是它的 ppid 却是一样的,这是为什么呢?...原因是我们想让子进程协助父进程完成一些任务,这些工作是单线程解决不了的,比如上面的代码中,父进程执行播放任务,子进程执行下载任务。...我们的进程在运行的时候,是会使用这些寄存器的,我们的进程,会产生各种数据,这些数据都会在寄存器中临时保存。...所以,CPU寄存器硬件只有一套,而10个进程的上下文数据应该有10套,因为寄存器不等于寄存器中的内容!

    11910

    MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 --Trap -- 中

    所以现在只有当代码在supervisor mode,才可能在程序运行的同时而不崩溃。所以,从代码没有崩溃程序计数器的值推导出我们必然在supervisor mode。...所以现在,ecall帮我们做了一点点工作,但是实际上我们离执行内核中的C代码还差的很远。接下来: 我们需要保存32个用户寄存器的内容,这样当我们想要恢复用户代码执行时,我们才能恢复这些寄存器的内容。...所以,每个寄存器被保存在了偏移量+a0的位置。这些存储的指令比较无聊,我就不介绍了。 当与a0寄存器进行交换,trapframe的地址是怎么出现在SSCRATCH寄存器中的?...为什么内核要保存寄存器的原因,是因为内核即将要运行会覆盖这些寄存器的C代码。...另一个问题是,为什么这些寄存器保存在trapframe,而不是用户代码的栈中?

    32940

    Linux之进程信号(下)

    3.信号集操作函数 sigset_t类型对于每一种信号用一个bit来表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现,用户(使用者)角度不必关心,用户只能调用一下函数来操作...如何分辨是用户态还是内核态 一个进程在执行的时候,需要将进程的上下文数据放到CPU中的寄存器中,CPU中有许多寄存器这些寄存器可以分为可见寄存器(eax、ebx…)不可见寄存器(状态寄存器…)。...这些寄存器在进程中具有特定的作用,例如寄存器的内容可以指向进程PCB、保存当前用户级页表,指向页表起始地址。寄存器中的CR3寄存器存储的内容表示当前进程的运行级别:0表示内核态,3表示用户态。...除了用户级页表外还有内核级页表,OS为了维护虚拟到物理之间的OS级的代码所构成的内核级映射表,开机时就将OS加载到内存中,OS在物理内存中只保存一份(OS只有一份),因此,OS的代码和数据在内存中只有一份...首先OS读取当前进程在CPU中CR3寄存器的内容,读取运行状态,只有当内容是0内核态才允许进行访问,所以系统调用接口的起始位置会帮我们把用户态变为内核态(即,从3改为0)。

    23420

    图说ARMv8架构特点

    我们从5个方面描述: 1,AArch64,A64指令集,这里有一个误解是,64bit的指令集是指通用寄存器是64位宽的,而不是指32位的指令集编码变成64位的。...ARMv7之前,关键字处理器模式privilege level: 处理器工作模式有:User、FIQ、IRQ、Abort、Undefined、System等, 不同的处理器模式有不同的权限privilege...主要有主要有2个level,privilegenon-privilege。其中只有User模式属于non-privilege level,其它均是privilege level。...这些处理器模式,除User模式外,其它模式基本上各类异常一一对应。...3)只有在异常发生(或者异常处理返回),才能切换Exception level(这也是Exception level的命名原因,为了处理异常)。

    2.9K70

    【Linux】进程信号

    ,这些宏定义可以在signal.h中找到 man 7 signal可以查看信号详细信息的命令 Term是正常结束,OS不会做额外的工作,Core代表OS初了终止的工作,还有其他工作。...而实际上当我们自己运行进程,我们的进程就变成前台进程了,而bash自动被切到后台。...实际上这种方法是比较慢的,为什么?打印是要进行输出的,输出是外设,外设IO较慢。...“有效”“无效”的含义是该信号是否处于未决状态 4.信号集操作函数 sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现,从使用者的角度是不必关心的...OS读取CPU中的CR3寄存器,读取运行状态,当是0内核态才能去进行访问,所以系统调用接口起始的位置会帮我们把用户态变成内核态,从3号状态改成0号状态。

    18010

    Hypervisor Necromancy;恢复内核保护器(1)

    一、使用EL1 转换表(存储在转换表基址寄存器 TTBRn_EL1) 由 EL1 控制,虚拟地址 (VA) 被转换为 中间物理地址 (IPA),而不是物理地址 (PA) 标准流程。...然后 IPA 由管理程序转换为 PA 使用 Stage 2 转换表(存储在 Virtual Translation Table 基本寄存器 VTTBR_EL2) 完全由 EL2 控制,而不是 EL1 可访问...----[ 1.3 - 工作区环境 如前所述,目标三星版本是 G955FXXU4CRJ5 QEMU 版本是 4.1.0。管理程序和我们的框架都是 64 位 ARM 二进制文件。...同样,对于 EL3,我们只期望 来自较低级别 AArch64 模式的同步异常。结果只有 相应的“vectors_el3”条目(+0x400)已设置,所有其他条目都会导致 系统挂起与 EL1 向量一样。...我们遵循`smc`调用约定[05],存储 W0 寄存器中的函数标识符寄存器 X1-X6 中的参数 (即使我们只使用一个参数)。如果函数标识符是 未知,然后系统挂起,模糊测试中的一个重要决定 设置。

    3K540

    为什么 Linux 系统调用会消耗较多资源

    执行 Hello World 程序时触发的多数系统调用都是程序启动触发的,只有 munmap 后的系统调用才是 printf 函数触发的,作为应用程序我们能做的事情非常有限,很多功能都需要依赖操作系统提供的服务...图 3 - 系统调用的三种方法 从上面的系统调用与函数调用的基准测试中,我们可以发现不使用 vSDO 加速的系统调用需要的时间是普通函数调用的几十倍,为什么系统调用会带来这么大的额外开销,它在内部到底执行了哪些工作呢...; 在系统调用表 ia32_sys_call_table 中查找对应的系统调用实现并传入寄存器的值; 系统调用在执行期间会检查参数的合法性、在用户态内存内核态内存之间传输数据,系统调用的结果会被存储到...总结 当我们在编写应用程序时,系统调用并不是一个离我们很远的概念,一个简单的 Hello World 会在执行时触发几十次系统调用,而在线上出现性能问题,可能也需要我们与系统调用打交道。...,我们需要使用操作系统提供的服务才能编写功能丰富的用户程序。

    1.9K40
    领券