不管什么样的操作系统什么样的计算架构,内存大致可以分为四个部分:

  (1)代码区:这个区域存储着被装入执行的二进制机器代码,处理器会到这个区域取指并执行。

  (2)数据区:用于存储全局变量等。

  (3)堆区(heap):一般由程序员分配释放,进程可以在堆区动态地请求一定大小的内存,并在用完之后归还给堆区。动态分配和回收是堆区的特点。

  (4)栈区(stack):系统自动分配释放 ,用于动态地存储函数之间的关系,以保证被调用函数在返回时恢复到母函数中继续执行。




假设这里有一个大箱子,有语文数学英语物理书,我要把这些书装进这个箱子里。应该怎么装

当然是一本一本的垒起来

并且 还要给最上面的一本书做个标记,这里以 红色五角星代替
并且如果我继续往里面放书,这个标记总会给最上面的一本书

请问如果我要拿走一本书,只能拿走哪本书?
肯定是物理书,因为它在最上面,并且我拿走它以后会把标记修改(标记总是给最上面的一本书)

了解了上面这个过程,我们再来理解栈

这个箱子就是箱子->栈
最上面一本书的标记是栈顶标记红色五角星->栈顶标记
把书往箱子里放这个过程叫做入栈放书进箱子->入栈
从箱子最上面把物理书拿走的这个过程叫做出栈把书拿出来->出栈

那么其实,你放的数据存放的位置内存地址栈顶标记也是内存地址

在汇编里面 入栈是push指令,出栈是pop指令

入栈 PUSH将16位寄存器 或者 内存中的字型数据 -> 栈顶标记的上面

出栈 POP将栈顶标记所标识的字型数据 ->16位寄存器或者内存中

并且它们会不断的修改栈顶标记(总在最上面)




PUSH指令:

在栈中存储数据的命令,以16位为单位存储

一般格式:PUSH 源操作数

PUSH	AX	;将AX的内容压入到栈里
PUSHF	;将标志寄存器的内容保存到栈中

入栈1.修改SP寄存器中的数值 sp=sp-2
2.将AX中字型数据存放到SS(段地址寄存器)和SP(偏移地址寄存器)所组合出来的内存地址中




POP指令:

将栈顶部的数据弹出至目的地的指令

一般格式:POP 源操作数

POP DX ; 将栈的顶部内容送到DX中
POPF ; 将栈的顶部内容作为标志寄存器弹出

出栈1.将SS(段地址寄存器)和SP(偏移地址寄存器)所组合出来的内存地址中的字型数据 存放到BX里
2.修改栈顶标记 SP=SP+2 成为新的栈顶标记




遵循 先进后出 (后进先出)




当AX=1122H、BX=3344H、CX=5566H时的堆栈中的行为

  PUSH	AX
  PUSH	BX
  PUSH	CX

  POP	CX
  POP	BX
  POP	AX




例:将AX和BX、WORD1和WORD2的内容相互替换

     PUSH     AX	; 把AX的内容推到栈中
     PUSH     BX	; 把BX的内容推到栈中
     PUSH     WORD1	; 把WORD1的内容推到栈中
     PUSH     WORD2	; 把WORD2的内容推到栈中

     POP       WORD1	; 将顶部(WORD2)还原到WORD1
     POP       WORD2	; 将顶部(WORD1)还原到WORD2
     POP	  AX	; 将顶部(BX)还原到AX
     POP	  BX	; 将顶部(AX)还原到BX




例2:使用堆栈编写程序,以相反的方式输出输入的字符

.MODEL SMALL
.STACK 100H
.CODE
MAIN 	PROC
	MOV	AH,2
	MOV	DL,'?'
	INT	21H	;输出回车

	XOR	CX,CX	;CX初始化0

	MOV	AH,1
	INT	21H	;键盘输入
 
@WHILE:
	CMP	AL,0DH
	JE	@END_WHILE	;如果是回车就跳转END_WHILE

	PUSH	AX	;把AX的内容推到栈里
	INC	CX	;CX加1

	INT	21H	;键盘输入
	JMP	@WHILE	;继续循环

@END_WHILE:
	MOV	AH,2
	MOV	DL,0DH
	INT	21H
	MOV	DL,0AH
	INT	21H	;输出回车换行 

	JCXZ	@EXIT	;cx=0的时候跳转EXIT

	MOV	AH,2	;输出
@TOP:
	POP	DX	;把栈顶部的还原到DX里
	INT	21H	;输出

	LOOP	@TOP	;循环直到CX=0,每循环一次CX-1
@EXIT:
	MOV 	AH,4CH 	
	INT 	21H
MAIN	ENDP
	END 	MAIN




字节序Endianness

往一个地址中写入一个数据,那么在内存中是如何存放这个数据的呢?

存储方法:大端字节序(Big-endian) 、小端字节序(Little-endian) 和 中端字节序(Middle-endian)

种类0x1234的形式0x12345678的形式
大端字节序12 3412 34 56 78
小端字节序34 1278 56 34 12
中端字节序-34 12 78 56

56 78 12 34

在这里0x1234:高位字节是0x12,低位字节是0x34

总结下来:

  • 大端字节序:高位字节在前,低位字节在后
  • 小端字节序:低位字节在前,高位字节在后

最后修改:2022 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏