前面說到前兩行代碼是為了賦值一個(gè)基址,好讓電腦啟動(dòng)的時(shí)候可以找到我們的代碼。今天接下來講下面幾行代碼
mov ax,#BOOTSEG ! 0x07c0
mov ds,ax
mov ax,#INITSEG ! 0x9000
mov es,ax
mov cx,#256
sub si,si
sub di,di
rep
movw
有了前面的兩行代碼的經(jīng)驗(yàn),我們可以很快知道
mov ax,#INITSEG ! 0x9000
mov es,ax
mov cx,#256
這三行代碼的作用就是把0x9000賦值給es,256(這個(gè)就是十進(jìn)制的256)賦值給cx。
再看看sub這個(gè)指令,這個(gè)是減法
舉例:
sub a, b
實(shí)際上就相當(dāng)于 a = a - b
所以下面這兩行代碼就相當(dāng)于給si和di清0
sub si,si
sub di,di
當(dāng)上面的代碼執(zhí)行完后,就變成了下面這樣
ds = 0x07c0
es = 0x9000
cx = 256
si = 0
di = 0
結(jié)合寄存器結(jié)構(gòu)圖來看

那么這么賦值的作用是什么呢?
我們繼續(xù)看后面的代碼
rep
movw
這個(gè)指令的意思是重復(fù)執(zhí)行movw,rep就是repeat。
這段代碼的執(zhí)行如下圖所示問:重復(fù)多少次呢?
答:這就要看計(jì)數(shù)寄存器了,也就是CX,在這里就是256次。
問:movw是干嘛的?
答:move world ,移動(dòng)(也可以說是復(fù)制,因?yàn)橹暗牟粫?huì)被刪)一個(gè)字(16bit),在這個(gè)語境里就是移動(dòng)256個(gè)字,也就是512個(gè)byte(1 word = 2 byte,1 byte = 8 bit)
問:移動(dòng)誰?移到哪?
答:是從 ds:si 處復(fù)制到 es:di 處。在當(dāng)前語境下就是從 0x07c0 -> 0x9000,上一篇說過,基址的計(jì)算會(huì)先左移4位,所以實(shí)際上是從0x7c00復(fù)制到0x90000(這里多了一個(gè)0),一共復(fù)制512個(gè)字節(jié)

接著往下看代碼
jmpi go,INITSEG ! 0x9000
go: mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,#0xFF00 ! arbitrary value >>512
jmpi 是一個(gè)跳轉(zhuǎn)指令,表示跳轉(zhuǎn)到 0x9000:go 處執(zhí)行。go是一個(gè)標(biāo)簽,編譯后會(huì)變成一個(gè)偏移地址。由前面我們可以得知,內(nèi)存里實(shí)際上存放著兩塊一樣的代碼,也就是說go的標(biāo)簽對(duì)應(yīng)的代碼也有兩塊,一個(gè)是相對(duì)于0x7c00的,另一個(gè)是相對(duì)于0x90000的,而這里要跳轉(zhuǎn)的是相對(duì)于0x90000的(這里為什么多了一個(gè)0,前面有講過,忘了翻回去看看)。
跳轉(zhuǎn)過去之后要執(zhí)行的代碼其實(shí)就是后面的
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,#0xFF00

go后面的代碼,其實(shí)都是mov指令,很好理解,就是把cs 賦值給ds、es、ss,最后把0xFF00賦值給sp。那么cs的值是多少呢?我們知道CPU執(zhí)行的指令,是由cs : ip 決定的,所以cs就是當(dāng)前代碼指令的地址。前面執(zhí)行了
jmpi go,INITSEG,所以cs就是0x9000,ip是偏移量go。mov ss,ax ; mov sp,#0xFF00這兩句代碼的含義就是設(shè)置堆棧指針為ss+sp,也就是0x9FF00寄存器的值如下圖所示
