汇编语言练习_1_数字分解_显示
文章目錄
- 環境
- 1、Bochs虛擬機
- 2、VirtualBox
- 工具
- 1、notepad++
- 2、nasm
- 思路
- 第一步:
- 第二步:
- 第三步:
- 第四步:
- 第五步:
- 第六步:
- 第七步:
- 解析
- 1、第二行中jmp code
- 2、計算字符串長度
- 3、ds為何為0x07c0
- 5、loop s解釋
- 6、第111行加上0x30的原因
- 7、除法指令解析
- 8、數字分解原理
- 9、為何屏幕顯示的數字是逆序的
- 10、結尾的字符填充
- 效果
- 1、要求
- 2、virtualbox
- 3、bochs
- 代碼
- 1、匯編代碼
- 2、機器碼 對照 匯編代碼
環境
1、Bochs虛擬機
代碼調試
2、VirtualBox
BIOS運行
工具
1、notepad++
編寫代碼
2、nasm
編譯工具
思路
第一步:
定義將要輸出的十進制數據
第二步:
創建存儲分解位數的空間,并填入-16,后面-16在輸出到顯存上的時候會加上0x30,變為空格所對應的ASCII碼
此時實際內存情況:
第三步:
對122進行分解,并將分解結果存儲到第二步創建的空間
此時實際內存情況:
第四步:
對45536進行分解,并將分解結果存儲到第二步創建的空間
此時實際內存情況:
第五步:
對195535進行分解,并將分解結果存儲到第二步創建的空間
此時實際內存情況:
第六步:
將分解結果輸出到顯存上,輸出到顯存的代碼解析
此時實際顯存情況:
前4行就是我們輸出到顯存上的數據
舉例說明:
0x31就是十進制的48,48作為ASCII碼對應的字符就是1,0x07就是它的屬性(前后背景及其顏色)
0x39就是十進制的56,56作為ASCII碼對應的字符就是9,0x07就是它的屬性(前后背景及其顏色)
屏幕輸出:
……
第七步:
$獲取當前偏移地址,jmp指令跳轉至當前偏移地址,形成死循環
解析
1、第二行中jmp code
是為了跳過數據段,執行代碼
2、計算字符串長度
標號data_res與標號code表示偏移,所以相減能夠得到字符串長度
3、ds為何為0x07c0
因為BIOS程序會被加載到0x0000 : 0x7c00,所以該程序的起始段地址就是0x07c0
5、loop s解釋
loop與cx配合能夠起到for循環的效果
當cx不為零,程序跳轉至s執行
當cx為零時,則按照順序執行
6、第111行加上0x30的原因
第二步創建的空間存儲的是一個個數字,需要轉換為其對應的ASCII碼,加上0x30,就能進行轉換
7、除法指令解析
鏈接
8、數字分解原理
122 / 10 =12…2
12 / 10 = 1…2
1 /10 =0…1
9、為何屏幕顯示的數字是逆序的
實際內存:
數字分解時是逆序分解,各個數字填入第二步創建的空間時,應該是221 63554 535591
為了正常看到數字,我在輸出到顯存的時候是倒著輸出的
就變成了 195535 45536 122
但是也可以將它們按照正常的順序輸出到顯存,不過取數據的時候就得跳來跳去的取數據,索性就倒著輸出
10、結尾的字符填充
我寫的是BIOS程序,計算機對BIOS程序的要求就是512字節,且以0x55,0xAA結尾
效果
1、要求
將數字122,45536,195535輸出到屏幕上
2、virtualbox
3、bochs
代碼
1、匯編代碼
start:jmp codedata: db 122 ;1bytedw 45536 ;2bytedd 195535 ;4byte data_res: db 0,0,0,-16db 0,0,0,0,0,-16db 0,0,0,0,0,0code:;指向數據地址 ds:simov ax,0x07c0mov ds,axmov si,data;指向存儲數據地址 es:dimov es,axmov di,data_res;分解開始:16位除法 ax存被除數,bl存除數,al存商,ah存余;被除數設置xor ax,axmov al,[ds:si]inc si;除數設置xor bx,bxmov bl,10mov cx,3 l0:;結果計算div blmov [es:di],ahinc dixor ah,ahloop l0inc di;留給空格;分解開始:32位除法 ax存被除數低2字節,dx存被除數高2字節,bx存除數,ax存商,dx存余;被除數設置xor ax,axxor dx,dxmov ax,[ds:si]inc siinc si;除數設置xor bx,bxmov bl,10mov cx,5 l1:;結果計算div bxmov [es:di],dlinc dixor dx,dxloop l1inc di;留給空格;分解開始:32位除法 ax存被除數低2字節,dx存被除數高2字節,bx存除數,ax存商,dx存余;被除數設置xor ax,axxor dx,dxmov ax,[ds:si]inc siinc simov dx,[ds:si]inc siinc si;除數設置xor bx,bxmov bl,10mov cx,6 l2:;結果計算div bxmov [es:di],dlinc dixor dx,dxloop l2code1:;es指向顯存,di做指針mov ax,0xB800mov es,axmov di,0x0;ds指向待寫入數據,si做指針mov ax,0x07c0mov ds,axmov ax,codemov si,ax;循環計數器mov cx,code-data_resl3:;寫顯存;al做中轉站dec simov al,[ds:si]add al,0x30;數字轉字符串mov byte [es:di],alinc dimov byte [es:di],0x07inc diloop l3jmp $ current:times (510-(current-start)) db 0db 0x55,0xAA2、機器碼 對照 匯編代碼
1 start:2 00000000 EB17 jmp code3 4 00000002 7A data: db 122 ;1byte5 00000003 E0B1 dw 45536 ;2byte6 00000005 CFFB0200 dd 195535 ;4byte7 data_res: 8 00000009 000000F0 db 0,0,0,-169 0000000D 0000000000F0 db 0,0,0,0,0,-1610 00000013 000000000000 db 0,0,0,0,0,011 12 code:13 ;指向數據地址 ds:si14 00000019 B8C007 mov ax,0x07c015 0000001C 8ED8 mov ds,ax16 0000001E BE[0200] mov si,data17 18 ;指向存儲數據地址 es:di19 00000021 8EC0 mov es,ax20 00000023 BF[0900] mov di,data_res21 22 ;分解開始:16位除法 ax存被除數,bl存除數,al存商,ah存余23 ;被除數設置24 00000026 31C0 xor ax,ax25 00000028 3E8A04 mov al,[ds:si]26 0000002B 46 inc si27 28 ;除數設置29 0000002C 31DB xor bx,bx30 0000002E B30A mov bl,1031 32 00000030 B90300 mov cx,333 l0:34 ;結果計算35 00000033 F6F3 div bl36 00000035 268825 mov [es:di],ah37 00000038 47 inc di38 00000039 30E4 xor ah,ah39 0000003B E2F6 loop l040 41 0000003D 47 inc di;留給空格42 43 ;分解開始:32位除法 ax存被除數低2字節,dx存被除數高2字節,bx存除數,ax存商,dx存余44 ;被除數設置45 0000003E 31C0 xor ax,ax46 00000040 31D2 xor dx,dx47 00000042 3E8B04 mov ax,[ds:si]48 00000045 46 inc si49 00000046 46 inc si50 51 ;除數設置52 00000047 31DB xor bx,bx53 00000049 B30A mov bl,1054 55 0000004B B90500 mov cx,556 l1:57 ;結果計算58 0000004E F7F3 div bx59 00000050 268815 mov [es:di],dl60 00000053 47 inc di61 00000054 31D2 xor dx,dx62 00000056 E2F6 loop l163 64 00000058 47 inc di;留給空格65 66 ;分解開始:32位除法 ax存被除數低2字節,dx存被除數高2字節,bx存除數,ax存商,dx存余67 ;被除數設置68 00000059 31C0 xor ax,ax69 0000005B 31D2 xor dx,dx70 0000005D 3E8B04 mov ax,[ds:si]71 00000060 46 inc si72 00000061 46 inc si73 00000062 3E8B14 mov dx,[ds:si]74 00000065 46 inc si75 00000066 46 inc si76 77 ;除數設置78 00000067 31DB xor bx,bx79 00000069 B30A mov bl,1080 81 0000006B B90600 mov cx,682 l2:83 ;結果計算84 0000006E F7F3 div bx85 00000070 268815 mov [es:di],dl86 00000073 47 inc di87 00000074 31D2 xor dx,dx88 00000076 E2F6 loop l289 90 91 code1:92 ;es指向顯存,di做指針93 00000078 B800B8 mov ax,0xB80094 0000007B 8EC0 mov es,ax95 0000007D BF0000 mov di,0x096 97 ;ds指向待寫入數據,si做指針98 00000080 B8C007 mov ax,0x07c099 00000083 8ED8 mov ds,ax100 00000085 B8[1900] mov ax,code101 00000088 89C6 mov si,ax102 103 ;循環計數器104 0000008A B91000 mov cx,code-data_res105 106 l3:107 ;寫顯存108 ;al做中轉站109 0000008D 4E dec si110 0000008E 3E8A04 mov al,[ds:si]111 00000091 0430 add al,0x30;數字轉字符串112 00000093 268805 mov byte [es:di],al113 114 00000096 47 inc di115 00000097 26C60507 mov byte [es:di],0x07116 117 0000009B 47 inc di118 0000009C E2EF loop l3119 120 0000009E EBFE jmp $121 current:122 000000A0 00<rep 15Eh> times (510-(current-start)) db 0123 000001FE 55AA db 0x55,0xAA總結
以上是生活随笔為你收集整理的汇编语言练习_1_数字分解_显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 8086汇编_除法指令
- 下一篇: 4.3 欠拟合与过拟合