汇编学习笔记
程序加载到内存中,从逻辑上来看是线性的,所有指令都会存在代码段中,用CS:IP指向内存单元,就可以执行指令。指令缓冲器->执行控制器
bx存放偏移地址,cx计数器
【address】代表偏移地址 DS是数据寄存器,可以对通用寄存器(ax,bx,cx,dx)进行读写,也可以对内存地址中的数据进行读写 mov ax,1000H mov ds,ax mov ax,[0]
内存空间中的一段,可以是数据段,也可以是代码段,看程序猿怎么去定义
将asm源代码编译链接成exe程序 asm->obj->exe 源代码: assume cs:codesg
codesg segment mov ax,1001H mov bx,ax codesg ends
end
用debug工具单步执行 -r查看信息 -t单步 -p终止
loop指令和cx寄存器对应,loop指令其实是do-while循环,先cx=cx-1,再判断是否为0,0的话就终止。 loop中的标号要在前面
如果是mov ax,ffffH,必须写成mov ax,0ffffH,加个0,因为编译器的问题
把内存地址中1000:0011~1000:0018累加,存放到dx中 mov ax,1000H mov ds,ax mov dx,0 mov bx,0011H mov cx,8 s:add dx,[bx] add bx,1 loop s
包含多个段的程序
db 'Hello World' 单引号定义字符。英文只需要前8位,所以用db,dw就浪费空间
mov ax,[bx+100] 更灵活定位内存地址 mov ax,100[bx] mov ax,[bx].100
例题:将第一个字符串改为大写,第二个字符串改为小写 assume cs:code ds:data
data segment db 'BaSiC' //改为大写,第5位都是0 db 'UniX' //改为小写,第五位都是1 data ends
code segment start: mov ax,data mov ds,ax
mov bx,0
mov cx,5
s1: and al,11011111 mov [bx+cx],al loops1
mov bx,5
mov cx,5
s2: and al,11011111 mov [bx+cx],al loop s2 code ends
end start
c语言中的int a[5] 其实就是:a代表第一个元素在ds中的偏移量,[5]代表长度
SI和DI寄存器与bx功能相近,但是它们两个不能拆成两个来用,bx却可以拆成bh和bl来用
习题:将一段字符串复制到它后面的内存空间,用SI和DI来实现(si:source di:destination) assume cs:code,ds:data
data segment db 'hello world' db '...........' data ends
code segment start: mov ax,data mov ds,ax mov si,0 mov di,12 mov bx,0 mov cx,6 s: mov ax,[si] mov [di],ax add si,2 add di,2 loop s code ends
end start
!!!学习问题:可以mov [di],[si]吗?嵌套循环中的cx寄存器(1.可以在外层暂时保留一个副本. 2.使用栈结构)?dx是干嘛的? 将数据全部转成大写 assume cs:code,ds:data,ss:stack
data segment db 'heLLo' db 'woRld' data ends
stack segment dw 0,0,0,0,0,0,0 stack ends
code segment start: mov ax,data mov ds,ax mov ax,stack mov ss,ax r: mov cx,2 push ax
mov bx,0
mov cx,5
c: and [bx], loop c
pop ax
loop r
code ends
end starts
bp的解释,是干嘛用的
一般来说,用[bx+idata+si]的方式来访问结构体,可以对比一下C语言中的结构体
除法 div暂时先不看
伪指令 dd (double word 双字->4个字节) dup (重复) db 3 dup('hello')
offset s (取得标号s的偏移地址)
jmp跳转原理需要多看看 jmp short 标号->修改ip 表示短转移,一个字节,只能-128~127,编译器在编译的时候就确定偏移位置。为什么用偏移不用绝对地址,因为地址有可能改变。 jmp near ptr 标号->修改ip 表示近转移,2个字节,范围比较大 jmp far ptr 标号->修改cs:ip 远转移,段转移
jmp word ptr ds:[0] 段内近转移
jcxz 有条件的跳转,类似高级编程语言中的if 题目:在2000H段内查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中? assume cs:code,ds:data
code segment start: mov ax,2000H mov ds,ax mov bx,0 s: mov ax,ds[bx] ;判断
jump short s
code ends
call和ret
什么是芯片 什么是端口
end start