计算机编程基础之一:计算机组成结构与常用编程操作

计算机的组成结构

程序员眼中的计算机

1.内存

存储字节的顺序:大端、小端;
为了加快CPU访问速度:数据对齐

2.CPU

ALU:进行算术操作和逻辑操作;
registers:用来装各种这样的数据,用来与ALU,MEM打交道。PC指示将要取的程序地址;SP用内存中的栈指针。
控制单元

3.IO

除了内存与CPU以外的设备,统称为输入/输出设备

常用编程操作

本节主要是搞清楚常用的C/C++代码操作对应的汇编语言是什么,在实际机器中的表现形式是什么样的。
搞明白了之后,就对一些语法特性就自然明了。
常用方法:
1.通过查看编译器生成的汇编代码。可以去反汇编网站实时查看 https://godbolt.org/
2.调试时查看反汇编代码

1.数据操作

基本汇编操作

将常量装入REG

将内存里数据装入REG

将REG里数据装入内存

定义变量并赋值

获取变量的值

计算数据所在的内存地址

在ARM中采用相对寻址方式,也叫偏移寻址(offset addressing),来计算要访问的数据地址

内存地址 语法 示例
Rn [Rn] [R5]
Rn + constant [Rn, #constant] [R5,#100]
Rn + Rm [Rn,Rm] [R4,R5]
Rn + (Rm << constant ) [Rn ,Rm LSL #constant ] [R4,R5,LSL #2]

C数组下标为什么会是从0开始?
为编译器方便地转换为汇编代码。机器中有相对寻址命令,访问数组元素的语句可以直接翻译成一个汇编代码,下标就对应着汇编中的offset

内存寻址实例

采用指针法查找

采用数组下标法查找

采用结构体引用查找

REGS与内存数据交换--栈操作

栈是一种“后进先出”的数据结构,在内存中是一片连续的空间,这块空间的操作地址叫栈指针(stack pointer,简写成SP);
对ARM处理器来说,它支持的栈是满减栈,即SP永远指向新进来的元素,每进来一个元素,SP的值就减小,向内存低地址生长。
在ARM处理器中,栈用来保存和恢复CPU registers的值。

PUSH {reglist}	//将CPU regs值依次保存到栈空间
POP {reglist}	//将栈空间里的值依次赋值给CPU regs

变量之间的操作

算术运算

数字比较

逻辑运算

对单个变量的操作

位操作

2.控制结构

对程序执行流程的控制

按当前条件选择相应的操作

当有情况时,就执行A操作

对应代码

if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
   A操作
}

流程图如下
image

当有情况时,执行A操作;要不然就执行B操作

对应代码

if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
   A操作
} else {
  /* 在布尔表达式为 false 时执行 */
  B操作
}

流程图如下
image

当有许多种情况,需要不同的操作

当有情况1时,就执行A操作;
当有情况2时,就执行B操作;
当有情况3时,就执行C操作;
...
当以上情况都没有,就执行默认操作;

可以多个if语句来实现,但是看起来不简洁。
更好的是使用下面的语句。

对应代码

switch var {
	case value1:
		A操作
		break;
	case valule2:
		B操作
		break;
	case valule3:
		C操作;
		break;
    default:
        默认操作
}

流程图如下
image

注:
在GO语言中,变量var可以是任何类型,value1,value2,value3可以同类型的任意值;可以支持case value1, value2, value3的代码样式;
在C语言中,var只能是整形或枚举类型,value1,value2,value3只能是同类型的一个常量或字面量

反复执行相同规则的操作

for语句

for init; condition; post
{
}

init:一般为赋值表达式,给控制变量赋初值;
condition:关系表达式或逻辑表达式,用来说明循环成立的条件;
post:一般为赋值表达式,给控制变量增量或减量。

流程图如下:
image

for condition {}	//等价while
for(;;)			//等价while(1)

循环控制语句

break

Go 语言中 break 语句用于以下两方面:

  • 用于循环语句中跳出当前循环,并开始执行循环之后的语句。
  • break 在 switch(开关语句)中在执行一条 case 后跳出语句的作用。
  • 在多重循环中,可以用标号 label 标出想 break 的循环。(C只能用goto,或是在循环体里的变量来结束相应层的循环)

image

流程图如下
image

contine

Go 语言的 continue 语句 有点像 break 语句。但是 continue 不是跳出循环,而是跳过当前循环执行下一次循环语句。
for 循环中,执行 continue 语句会触发 for 增量语句的执行。
在多重循环中,可以用标号 label 标出想 continue 的循环。(C语言语法没有此功能,需要自己写相应逻辑)

image

流程图如下:
image

goto

Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

goto 语法格式如下:

goto label;
..
.
label: statement;

image

goto 语句流程图如下:
image

实现一个功能模块--函数

实现无参函数的调用

实现有参函数的调用

实现void函数的返回

实现函数返回值

实现函数局部变量的存储

posted @ 2021-07-08 11:00  海林的菜园子  阅读(409)  评论(0)    收藏  举报