日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

包含多个段的程序---汇编学习笔记

發布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 包含多个段的程序---汇编学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

包含多個段的程序

要使用一段安全的空間,第五章中我們說0:200~0:2ff是相對安全的。可這段代碼容量只有256個字節。

合法地通過操作系統取得的空間都是安全的。

程序取得所需空間的方法有兩種,一是加載程序的時候程序分配,再就是程序在執行的過程中向系統申請。

對于使用多個段的問題,我們將討論:
(1)在一個段中存放數據、代碼、棧,我們先來體會一下不使用多個段時的情況;
(2)將數據、代碼、棧放入不同的段中。


6.1 在代碼段中使用數據

考慮這樣一個問題,編程計算以下8個數據的和,結果存在ax寄存器中:
0123h、0456h、0789h、0abch、0defh、0fedh、0cbah、0987h
我們如何去尋找這個內存段的空間呢?(這里有代碼段和數據段)

從規范的角度來講,我們不能自己隨便決定哪段空間可以使用,應該由系統來分配。我們可以在程序中,定義我們希望處理的數據,這些數據就會被編譯、連接程序作為程序的一部分寫到可執行文件中。當可執行文件中的程序被加載入內存時,這些數據也同時被加載入內存中。與此同時,我們要處理的數據也就自然而然地獲得了存儲空間。

看具體程序:

assume cs:code code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ;dw代表是字型數據mov bx,0mov ax,0mov cx,8 s: add ax,cs:[bx]add bx,2loop smov ax,4c00hint 21hcode ends end

編譯、連接這段程序后,我們看到如下:

顯然,我們程序從cs:ip開始,而cs開始部分就是數據部分。明顯是我們程序在代碼段的dw影響了這段代碼開始執行的位置(更準確的說,是我們沒有定義數據段)。

那么,我們怎樣讓程序正確的(或說cs:ip)指向程序入口呢?如下:

assume cs:code code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hstart: mov bx,0mov ax,0mov cx,8 s: add ax,cs:[bx]add bx,2loop smov ax,4c00hint 21hcode ends end start

如上代碼所看到的,我們在兩處加了start

可執行文件中的程序執行過程如下:

  • 由其他的程序(Debug、command或其他程序)將可執行文件中的程序加載入內存;
  • 設置CS:IP指向程序的第一條要執行的指令(即程序的入口),從而使程序得以運行;
  • 程序運行結束后,返回到加載者。
  • 現在的問題是:我們由什么來判定程序入口呢?具體框架如下


    6.2 在代碼段中使用棧

    完成下面的程序,利用棧,將程序中定義的數據逆序存放。

    assume cs:code code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h? mov ax,4c00hint 21hcode ends end

    程序思路:定義的數據存放在cs:0~f單元中,我們只要將數據依次入棧,再依次出棧就可以逆序存放了。

    問題是:我們首先要有一段可當作棧的內存空間。如下:

    assume cs:code code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;用dw定義16個字型數據,在程序加載后,將取得16個字的;內存空間,存放這16個數據。后面的程序段中將這段空間;當作棧來使用start: mov ax,csmov ss,axmov sp,30h ;將設置棧頂ss:sp指向cs:30mov bx,0mov cx,8s: push cs:[bx]add bx,2loop s ;將代碼段0~15單元中的8個字型數據依次入棧mov bx,0mov cx,8s0: pop cs:[bx]add bx,2loop s0mov ax,4c00hint 21hcode ends end start

    自此,我們的程序段定義并且使用了,發現很麻煩。

    檢測點 6.1

    (1)下面程序實現依次使用內存0:0~0:15單元中的內容改寫程序中的呃數據,完成程序:

    assume cs:code code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hstart: mov ax,0mov ds,axmov bx,0mov cx,8 s: mov ax,[bx]mov cs:[bx],ax ;題目這段代碼為空,需要自己填寫add bx,2loop smov ax,4c00hint 21hcode ends end start

    (2)下面的程序實現依次內存0:0~0:15單元中的內容改寫程序中的數據,數據的傳送用棧來進行。棧空間設置在程序內。完成程序:

    assume cs:code code segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hdw 0,0,0,0,0,0,0,0start: mov ax,cs ;題目ax后面為__mov ss,axmov sp,20h ;題目ss后面為__mov ax,0mov ds,axmov bx,0mov cx,8s: push [bx]pop cs:[bx] ;題目為________add bx,2loop smov ax,4c00hint 21hcode ends end start

    6.3 將數據、代碼、棧放入不同的段

    在前面的內容中,我們在程序中用到了數據和棧,將數據、棧和代碼都放在了一個段里面。

    這樣做顯然有兩個問題:
    (1)把它們放在一個段中使程序顯得混亂
    (2)前面程序中處理的數據很少,用到的棧空間也很小,加上沒有很長的代碼,放到一個段里面沒有問題。但如果數據、棧和代碼需要的空間超過64KB,就不能放在一個段中。

    所以,應該考慮用多個段存放數據、棧和代碼。如下所示:

    assume cs:code,ds:data,ss:stack;數據段 data segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data ends;棧段 stack segmentdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 stack ends;代碼段 code segmentstart: mov ax,stackmov ss,axmov sp,20h ;設置棧頂ss:sp指向stack:20mov ax,datamov ds,axmov bx,0 ;設置ds:bx指向data段的第一個單元mov cx,8 s: push [bx]add bx,2loop s ;以上將data段中的0~15單元中的8個字型數據一次入棧mov bx,0mov cx,8 s0: pop [bx]add bx,2loop s0 ;以上依次出棧8個字型數據到data段的0~15單元中mov ax,4c00hint 21hcode endsend start

    程序說明:
    (1)定義多個段的方法
    定義一個段的方法和前面所講的定義代碼段的方法沒有區別,只是對于不同的段,要有不同的段名。
    (2)對段地址的引用
    現在,程序中有多個段了,如何訪問段中的數據呢?當然要通過地址,而地址是分為兩部分,即段地址和偏移地址。如何指明要訪問的數據的段地址呢?在程序中,段名就相當于一個標號,它代表了段地址。(形如:mov ax,data)
    (3)“代碼段”、“數據段”、“棧段”完全是我們的安排

  • 我們在源程序中為這三個命名為code、stack、data
  • 我們在源程序中用偽指令“assume cs:code,ds:data,ss:stack”將它們關聯起來
  • 若要CPU按我們的安排行事,就要用機器指令控制它,源程序中的匯編指令是CPU要執行的內容。CPU如何知道執行它們?我們在源程序的最后用“end start”說明程序的入口,這個入口將被寫入可執行文件描述信息,可執行文件的程序被加載入內存后,CPU的CS:IP被設置指向這個入口,從而開始執行程序中的第一條指令。
  • 實驗 5 編寫、調試具有多個段的程序

    (1)將下面的程序編譯連接,用Debug加載、跟蹤,然后回答這個問題。

    assume cs:code,ds:data,ss:stackdata segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h data endsstack segmentdw 0,0,0,0,0,0,0,0 stack endscode segment start: mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpush ds:[0]push ds:[2]pop ds:[2]pop ds:[0]mov ax,4c00hint 21hcode ends end start

    1.CPU執行程序,程序返回前,data段的數據為多少?

    2.CPU執行程序,程序返回前,cs=?、ss=?、ds=?。

    3.設置程序加載后,code段的段地址為X,則data段的段地址為?,stack段的段地址為?。
    code=X、data=X-20、stack=X-10。

    (2)將下面的程序編譯連接,用Debug加載、跟蹤,然后回答問題。

    assume cs:code,ds:data,ss:stackdata segmentdw 0123h,0456h data endsstack segmentdw 0,0 stack endscode segment start: mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpush ds:[0]push ds:[2]pop ds:[2]pop ds:[0]mov ax,4c00hint 21hcode ends end start

    1.CPU執行程序,程序返回前,data段中的數據為多少?

    2.CPU執行程序,程序返回前,cs=?、ss=?、ds=?。

    3.設程序加載后,code段的段地址為X,則data段的段地址為?,stack段的段地址為?。
    cs = X , ds = X-20, ss = X-10。
    4.對于如下定義的段:
    name segment
    ···
    name ends
    如果段中的數據占N個字節,則程序加載后,該段實際占有的空間為?。
    N/256取上整

    (3)將下面的程序編譯連接,用Debug加載、跟蹤,然后回答問題。

    assume cs:code,ds:data,ss:stackcode segment start: mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpush ds:[0]push ds:[2]pop ds:[2]pop ds:[2]mov ax,4c00hint 21hcode endsdata segmentdw 0123h,0456h data endsstack segmentdw 0,0 stack endsend start

    1.CPU執行程序,程序返回前,data段中的數據為多少?

    2.CPU執行程序,程序返回前,cs=?、ss=?、ds=?。

    3.設程序加載后,code段的段地址為X,則data段的段地址為?,stack的段地址為?。
    code=X , data=X+(code指令字節數/256)取上整+1 , stack = data + 1。

    (4)如果將(1)(2)(3)題中的最后一條偽指令“end start”改為“end”(也就是說,不指名程序的入口),則哪個程序仍然可以正確執行?請說明原因。

    第3個可以,首先是指令從何處開始,3可以正確的指向指令開始出,而其他兩個不行;其次,是指令結束,3個都可以正常結束,因為只要遇到mov ax,4c00h和int 21h執行完后,程序就返回了。

    (5)程序如下,編寫code段中的代碼,將a段和b段中的數據依次相加,將結果存到c段中。

    assume cs:codea segmentdb 1,2,3,4,5,6,7,8 a endsb segmentdb 1,2,3,4,5,6,7,8 b endsc segmentdb 0,0,0,0,0,0,0,0 c ends ;題目code需要自己編寫 code segment start:mov ax,cmov ds,axmov bx,0mov ax,amov es,axmov cx,8s: mov dl,0add dl,es:[bx]add dl,es:[bx+16]mov [bx],dlinc bxloop smov ax,4c0hint 21hcode ends end start

    實驗結果如下:

    (6)程序如下,編寫code段中的代碼,用push指令將a段中的前8個字型數據,逆序存儲到b段中。

    assume cs:codea segmentdw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0fh,0ffh a endsb segmentdw 0,0,0,0,0,0,0,0 b ends ;題目代碼段需要自己編寫 code segment start:mov ax,bmov ss,axmov sp,16mov ax,amov ds,axmov bx,0s: push [bx]add bx,2loop smov ax,4c00hint 21hcode ends end start

    實驗結果如下:


    本章完

    總結

    以上是生活随笔為你收集整理的包含多个段的程序---汇编学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。