汇编语言-转移指令

汇编里的转移指令是真多啊....函数

首先,在机器码里,转移不会给定目的地址,而是给出相对位移oop

1)无条件转移指令spa

jump short label // 段内转移   ip + 8位位移code

jump near ptr label // 段内转移 ip + 16位位移blog

jump far ptr label // 段间转移 cs:label所在段的段地址,ip:label所在段的偏移地址ip

jump 16位reg // ip = (reg)内存

2)条件转移指令it

jcxz label // 当cx=0时就转移到label ip + 8位位移class

因此loop的内部机制就是jcxz:LOOP,使用计数器 cx。进入循环前设置好,每循环一次自动-1.循环

3)call和ret

call label // 先push call下一条语句的ip,再jump near ptr label;相似的有 call far ptr label:依次push cs、push ip、jump far ptr label

ret // 先pop ip,再根据ip执行指令 ;相似的有 retf:依次pop ip、pop cs,再执行指令

双剑合璧,想一想都很厉害,子程序顺溜地来。

说到子程序,想起了VM language里的函数。

函数调用的流程是:先push主程序的一系列段地址以及returnAddress(这个是专门定义的一个label),再修改ARG令其指向实参,而后执行label后的语句,执行完先返回参数,再pop主程序的段地址,再goto returnAddress。

实际中使用的汇编语言处理子程序的流程相似:遇到call指令,先push ip或ip和cs,再执行子程序(在子程序里有时也会对寄存器内容进行入栈出栈操做),子程序结束处有ret,用于pop ip或ip和cs。

因此,Nand2Teris就是提供了一种实现计算机的基本思路,一通百通型。

 

举个栗子:显示器大小为25*80,即25行,每行80个字,每一个字由两部分组成:一个字节表示字符,一个字节表示属性(颜色背景)

请在显示器的第13行、35列显示 

Have fun with Assembly

慢慢来。

(1)怎么在显示器上显示字符?

显示器的段地址默认为B800h,利用偏移地址修改内存单元的内容便可。偏移地址为奇数就存放字符,偶数存放对应的属性。

(2)怎么在设置显示字符的属性?

属性由一个字节控制,即8个bite,分别为 闪烁 背景RGB 高亮 前景RGB,选择0/1。

好比说闪烁红底绿字就是 11000010B;黑底白字就是 00000111B 

(3)怎么显示一串字符?

很容易想到循环。

 

其实这上面这些概念性的都好理解,很差弄的是寄存器的使用和计算,须要考虑8位仍是16位,数据在寄存器间的传送,寄存器不够了咋整等等。

assume cs:code
data segment
db 'Have fun with Assembly!',0 data ends code segment start: mov dh,13 mov dl,35 mov cl,2 mov ax,data mov ds,ax mov si,0 call show_str mov ax,4c00h int 21h show_str:sub dh,1 mov al,160 mul dh mov bx,ax sub dl,1 mov al,2 mul dl add ax,bx mov bx,ax mov ax,0B800h mov es,ax mov al,cl captical:mov cl,ds:[si] mov ch,0 jcxz ok mov di,ds:[si] mov byte ptr es:[bx],di inc bx mov byte ptr es:[bx],al inc bx inc si jmp short captical ok: ret code ends end start
相关文章
相关标签/搜索