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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

程序的加载和执行(六)——《x86汇编语言:从实模式到保护模式》读书笔记26

發布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序的加载和执行(六)——《x86汇编语言:从实模式到保护模式》读书笔记26 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

程序的加載和執行(六)——《x86匯編語言:從實模式到保護模式》讀書筆記26


通過本文能學到什么?

  • NASM的條件匯編
  • 用NASM編譯的時候,通過命令行選項定義宏
  • Makefile的條件語句
  • 在make命令行中覆蓋Makefile中的變量值
  • 第13章習題解答
  • 復習如何構造棧段描述符

我們接著上篇博文說。
在我修改后的文件中,用到了條件匯編。
比如:

%ifdef DEBUGput_core_salt: ;打印內核的符號... ...put_usr_salt: ;打印用戶的符號...... %endif

下文對此進行講解。

1.條件匯編

與C預處理器相似,NASM允許對一段源代碼只在某特定條件滿足時進行匯編。
注意,C語言的預處理指令是由#字符開頭的一些命令,NASM編譯器的預處理指令由%開頭。

1.1 只在某特定條件滿足時進行匯編

%if<condition>;if <condition>滿足時接下來的代碼被匯編。......%elif<condition2>; 當 if<condition>不滿足,而<condition2>滿足時,該段代碼被匯編。......%else;當<condition>跟<condition2>都不滿足時,該段代碼被匯編。......%endif

%else跟%elif子句都是可選的,也可以使用多于一個的%elif子句。

1.2 測試單行宏是否存在

%ifdef DEBUG...%endif

如果我們定義了宏DEBUG,那么省略號處的代碼就會被匯編,否則不會。

以定義宏DEBUG為例,可以用兩種方法。

1.3 在代碼中直接定義宏

%define DEBUG

1.4 通過命令行選項

編譯文件的時候,用-d 宏名稱。

-d DEBUG

例如:

nasm c13_core.asm -o c13_core.bin -d DEBUG

注意:-d可以寫成-D,它和后面宏名之間的空格也可以不要。
例如:

nasm c13_core.asm -o c13_core.bin -dDEBUG

2.關于Makefile

因為加入了條件匯編,所以Makefile和上篇博文中的不太一樣。
上篇博文地址:
程序的加載和執行(五)——《x86匯編語言:從實模式到保護模式》讀書筆記25

修改后的Makefile如下。

DEBUG = 0BIN = c13_mbr.bin c13_core.bin c13.bin empty A_DIR = /home/cjy/a.img C_DIR = /home/cjy/c.imgall:$(BIN).PHONY:all cleanc13_mbr.bin:c13_mbr.asmnasm $< -o $@dd if=$@ of=$(A_DIR)c13_core.bin:c13_core.asm ifeq ($(DEBUG),1)nasm $< -o $@ -D DEBUG elsenasm $< -o $@ endifdd if=$@ of=$(C_DIR) bs=512 seek=1 conv=notruncc13.bin:c13.asmnasm $< -o $@dd if=$@ of=$(C_DIR) bs=512 seek=50 conv=notruncempty:diskdata.txtdd if=$< of=$(C_DIR) bs=512 seek=100 conv=notrunctouch $@clean:$(RM) $(BIN)

2.1 條件語句

首先,我們定義了一個變量(也被稱作宏)DEBUG,并給其賦值為0;
需要注意的是以下幾行:

ifeq ($(DEBUG),1)nasm $< -o $@ -D DEBUG elsenasm $< -o $@ endif

這里用到了Makefile的條件語句。執行make時,會根據運行時的不同情況選擇不同的執行分支。
在這個例子中,當變量DEBUG的值為1時,就執行nasm $< -o $@ -D DEBUG ;
當變量DEBUG的值不為1時,就執行nasm $< -o $@ ;

當我們想編譯帶調試信息的源文件,修改Makefile中DEBUG的值為1就可以了。

但是,還有沒有更簡單的方法呢?

2.2 在命令行中定義變量

當命令行中的變量(宏)定義跟makefile中的定義有沖突時,以命令行中的定義為準。所以,我們可以在執行make的時候加上變量=新值,以覆蓋Makefile文件中的變量值。

對于本文的例子,除了修改Makefile中DEBUG的值為1這種方法外,還有一種方法是在命令行中重新給變量(宏)賦值。

make "DEBUG=1"

注意:當沒有空格的時候,引號也可以省略。由于宏定義必須作為單個參數進行傳遞,所以要避免使用空格,所以更妥當的方法是使用引號。

3.第13章習題解答

在本章中,用戶程序只給出建議的棧大小,但并不提供棧空間。現在,修改內核程序和用戶程序,改由用戶程序自行提供棧空間。要求:棧段必須定義在用戶程序頭部之后。

在這里,我給出自己的答案,供學習者參考。

3.1 對于源文件c13.asm的修改

修改有兩處。第一處是:


由于棧空間由用戶程序提供,所以必須指明棧段的匯編地址和大小,這樣內核程序才能有足夠的信息為用戶創建棧段描述符。

第二處是:

因為題目已經要求棧段必須定義在用戶程序頭部之后,所以這里緊接著頭部定義棧空間。

小插曲
編譯這個文件,會報錯。

c13.asm:14: error: division operator may only be applied to scalar values make: *** [c13.bin] 錯誤 1

哦,這是為什么呢?我改成了

stack_len dd (stack_end-0)/(4*1024)

依然報同樣的錯誤。
通過查資料,發現有的朋友是這樣回答的:

A label is a relocatable value——its value is modified by the linker/loader.The difference between two labels(in the same section) is a scalar value, and NASM will work with it.

好吧,既然同一個section的兩個標號的差值是標量,那我這樣寫好了:

stack_len dd (stack_end-stack_start)/(4*1024)

其實stack_start這個標號之前是沒有的,是我為了做差值專門加上的。
你還別說,這樣寫真的管用,不報錯了。

3.2 對源文件c13_core.asm的修改

左邊的代碼(配書代碼),內核為用戶棧分配內存,然后計算棧的高端物理地址。
右邊的代碼(習題代碼),內核不需要分配內存,僅僅從頭部取出棧的起始地址,然后計算棧的高端物理地址。
這段代碼是我半年前寫的,可是現在讀起來也覺得陌生了。那就解釋一下最關鍵的3行,加深自己的記憶。

469 mov edx,edi 470 add edx,[edi+0x08] ; 棧段起始的線性地址 471 add eax,edx ; 得到棧的高端物理地址

此時,DS指向了0-4GB的數據段,EDI中的內容是用戶程序的加載地址。
469:EDX中是用戶程序的加載地址;
470:從用戶頭部偏移0x08處取得section.stack.start,加上用戶程序的加載地址(EDX),就得到了用戶棧的起始地址。如圖所示。
471:棧段描述符中的基地址,應該是棧空間的高端物理地址,所以還要加上棧的大小(在EAX中)。
如果不明白為什么這樣構造棧段描述符,可以參考我的博文:
如何構造棧段描述符

3.3 在Bochs中驗證程序

我們的修改對嗎?“實踐出真知”。

3.3.1 驗證思路

因為棧空間是用戶程序提供的,內核只是根據頭部信息創建對應的棧段描述符。所以我們要驗證的就是棧段描述符和用戶定義的棧是否相符。在上面提到的博文中,我已經詳細推導了如何構造棧段描述符。

用戶程序的頭部結構如下圖所示:

本實驗的用戶程序的符號表有3個符號,所以頭部總長度為0x328;由于用戶程序的加載地址是0x100000,所以棧空間的起始地址為0x100328;又因為棧空間大小定義為0x1000(4KB),所以棧空間的高端物理地址為0x100328+0x1000=0x101328,
這應該就是棧段描述符的基地址。

有效段界限應為0xFFFFFFFF-棧的大小(以字節為單位),即0xFFFFFFFF-0x1000=0xFFFFEFFF,這應該是棧段描述符中的段界限。

3.3.2 驗證結果

在Bochs中運行程序,跑起來后,Ctrl+C暫停程序,輸入info gdt可以查看GTD的信息。我們看到在下圖中:

黃色劃線的描述符與我們的推理相符。所以,我們的修改是正確的。

【end】

總結

以上是生活随笔為你收集整理的程序的加载和执行(六)——《x86汇编语言:从实模式到保护模式》读书笔记26的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 香蕉久热 | 欧美色图狠狠干 | 成年人网站av | 沟厕沟厕近拍高清视频 | 日本女人性视频 | 五月婷久久 | 日韩欧美一级 | 天天狠狠干 | 欧美成人精品在线观看 | 亚洲av无码专区国产乱码不卡 | 一本一道波多野结衣av黑人 | 欧美一级不卡 | 中国xxxx性xxxx产国 | 4438亚洲| 欧美日本激情 | 欧美一级做性受免费大片免费 | 国产午夜伦鲁鲁 | 可以看的毛片 | 午夜在线观看视频 | 亚洲精品丝袜 | av色成人| 欧美专区视频 | 日韩视频在线观看免费视频 | 欧美美女性生活 | 99久久国产精 | 白嫩少妇激情无码 | 91口爆一区二区三区在线 | 毛茸茸成熟亚洲人 | 国产精品videos | 精品人妻码一区二区三区红楼视频 | 日韩欧美视频在线免费观看 | 91精品国产乱码在线观看 | 免费av网页| 国产精品成人一区二区 | 久久99精品国产.久久久久久 | 老妇free性videosxx| 欧美日韩免费在线 | 日本55丰满熟妇厨房伦 | 欧美日韩一区二区三区在线观看 | 亚洲 小说区 图片区 都市 | 成人亚洲玉足脚交系列 | 亚洲毛片网 | 中文字幕第七页 | 国产成人小视频 | 伊人情人综合 | 免费又黄又爽又色的视频 | 快播91| 国产美女被遭强高潮免费网站 | 国内露脸中年夫妇交换 | 国产99久久久久久免费看 | 91视| 亚洲精品一区二区口爆 | 欧美激情videos| 欧美日韩一区二区三区四区 | 视频精品一区二区 | 综合久久久久久 | 六月色婷 | 中文字幕亚洲日本 | 不卡av电影在线 | 国产高清不卡视频 | 51热门大瓜今日大瓜 | 久久精品免费一区二区 | 国产伦精品视频一区二区三区 | 在线cao| 日韩综合在线视频 | 人体私拍套图hdxxxx | 亚洲一区av在线 | 国产无遮挡又黄又爽又色 | 亚洲第一页乱 | 西比尔在线观看完整视频高清 | 国产伦精品一区二区三区在线观看 | 久久男人av | 超碰人人cao | 日一日干一干 | 亚洲图片另类小说 | 久久人妻无码aⅴ毛片a片app | 天堂网2020| 国产91在线视频 | jizzjizz国产| 国产精品久久久久影院老司 | 先锋资源av在线 | 色播视频在线播放 | 欧美极品少妇×xxxbbb | www.色人阁| 欧美视频在线免费 | 一区二区三区免费在线视频 | 欧美乱色| 无码人妻aⅴ一区二区三区69岛 | 一本色道久久综合亚洲 | 污污视频免费观看 | 欧美在线你懂的 | 揉我啊嗯~喷水了h视频 | 欧美激情 在线 | 色乱码一区二区三区网站 | 国产短视频一区 | 国产免费av一区二区 | 91精品人妻一区二区三区蜜桃欧美 | av男人资源 | 91精品黄色 |