第三天的总结:
对于代码段,我们可以修改CS:IP这两个寄存器去指向我们定义的代码段这样CPU就将执行我们定义的代码段中的指令
对于栈段来说我们可以修改SS,SP这俩个寄存器去决定栈顶标记在哪里,这样CPU在执行栈的操作时,不如push pop就会将我们定义的栈段当作栈空间进行临时性的数据段存放或者取出
不管怎么安排CPU将内存中某段内容当作指令是因为CS:IP指向那里
CPU将某段内存当作栈空间是因为SS,SP指向那里
我们要清楚,我们如何安排内存,以及如何让CPU按照我们的安排去行事
那么数据从哪里来,指令从哪里来,临时性的数据存放到哪里去
取决于我们对CPU中的地址寄存器的设置 如CS IP SS IP DS寄存器
内存段的安全性问题
随意的向某一段内存空间中写入内容是非常危险的
mov 指令 由于我们不小心修改了系统存放在内存中的重要数据或者指令导致的程序的崩溃 系统的崩溃
像安全的的内存空间去写入内容
0:200~0:2FFH
-d 0:200 2FF
但是才256个字节太少了
那么我们可以使用操作系统分配给我们的内存空间
在操作系统的环境中,合法地通过操作系统取得的内存空间都是安全的
因为操作系统不会让一个程序所使用的内存空间和其他程序 以及系统自己的空间产生冲突
管理内存的程序:操作系统就是干管理内存的时期的
所以在操作系统允许的情况下 程序可以取得任意容量的内存空间
一种是系统加载程序时 程序分配的 内存空间
一种是程序在执行的过程中向一种再去申请内存
然后我们开始新的学习
编译和链接
编译masm 是将asm文件编译成obj文件
链接link 是将obj文件链接成exe文件
编译器是用来翻译软件的
那么为什么不一步将asm文件翻译成exe文件呢?
答:假如我们有100w行代码 编译器去翻译这100w行要翻译5分钟
但是我们代码是会有错误的 去修改几行代码再重新翻译就会耗费很多的时间
但是我们可以把这100w行代码拆分来
t1.asm -> obj
t2.asm -> obj
t3.asm -> obj
······
t1000.asm -> obj
假如t2出错,我们只需要修改t2就可以了
再通过链接把所有的obj文件链接再一起
得到最终的exe文件
EXE可执行文件
系统要运行exe文件需要分配给他一段内存
系统要怎么知道要分配多大的内存给这个程序?
因为exe文件中,除了整个程序的内存外还包括了一些信息
文件有多大 程序在哪里,系统就是根据这些描述信息对寄存器进行相关的设置
start伪指令 告诉翻译软件 我们设置的程序入口地址在哪里 记录在exe文件的描述信息中,然后通过这个描述去执行文件中的内容,去设置cs:ip,以及其他的内存
总结:exe可执行文件不止包括了我们整个程序,还包括了描述信息,系统根据这些描述信息进行相关的设置
源代码文件asm
汇编语言是由汇编指令、伪指令、符号系体系来布局的
汇编指令 被编译器翻译成010101001 机器指令 机器码由CPU执行的
伪指令 由编译器执行的
符号系体系 由编译器执行的
assume cs:code,ds:data,ss:stack ;assume 是假定的意思
code segment
mov bx,0B800H
mov es,bx
mov bx,160*10+40*2
mov word ptr es:[bx],5535H
mov ax,4c0H ;
int 21H
code ends
data segment ;告诉编译器 data段从这里开始,data可以随意去值,如:a segment,和下面的ends对应即可
db 128 dup (0)
data ends ;告诉编译器 data段从这里结束
stack segment stack
db 128 dup (0)
stack ends
end ;告诉编译器我们的代码到这里就完事了
段的名字可以随意取,但是得方便我们阅读和理解
add sub 是汇编指令 乘法在汇编语言中肯定有对应的汇编指令
mov ax,4c0H ;这两条指令的作用是执行程序的返回功能
int 21H
程序在加载程序的时候会给程序分配内存和设置寄存器
这两段汇编的作用就是把内存和寄存器都还给系统
如果不返回就会永远占用了内存
内存也是有限的 直到最终系统没有内存
程序的跟踪
debug+程序名
cx = 程序的长度
p执行 int指令
q退出
psp区 从ds:0开始的256个字节
我们程序的名字
系统加载程序到内存中
它是用来系统和程序之间执行的通信
一个程序:
用debug跟踪该程序的执行过程,写出每一步执行后,相关寄存器中的内容和栈顶的内容
assume cs:code
code segment
mov ax,2000H
mov ss,ax
mov sp,0
add sp,10H
pop ax
pop bx
push ax
push bx
pop ax
pop bx
mov ax,4C00H
int 21H
code ends
end
该程序的作用就是2000:0010中的 11 22出栈放到ax寄存器中,33 44放到bx寄存器中 然后push ax和push bx
入栈后内存中的值就交换了,随后出栈交换的ax bx两个寄存器的值
编写代码时我们应该注意到的点
mov ax,08800H 字母型数据前面必须有0 mov 8800H是错误的
10和10H的区别
10是10进制数 10H是16进制数
; 是注释