DOS中斷只有這些服務輸出到屏幕:
AH = 02h -WRITE CHARACTER TO STANDARD OUTPUT
AH = 06h - DIRECT CONSOLE OUTPUT
AH = 09h - WRITE STRING TO STANDARD OUTPUT
AH = 40h - "WRITE" - WRITE TO FILE OR DEVICE
(與標準輸出或STDERR文件句柄調用)所有這些只有副本從輸入到輸出的值,沒有任何轉換或格式化,所以通常您的輸入應該是ASCII字符ter或字符串或二進制字節數組。
但你應該明白,計算機工作在二進制(低電流/高電流,通常被解釋爲0或1)。它不瞭解任何其他價值。
所以,當你在CPU寄存器al
具有值69
,所述al
從CPU芯片8個單元創建的,並且這些單元被設置爲「0 1 0 0 0 1 0 1」。這些單元稱爲位。因此,當您在彙編源代碼mov al,45h
中編寫代碼時,彙編程序會在編譯過程中爲您創建此二進制表單,並將其作爲單字節存儲在機器代碼中,因爲mov al,imm8
指令需要編碼的值。
因此,「二進制字符串」所需做的只是從左到右逐位進行8次,並將字符'0'
或'1'
輸出到屏幕,具體取決於特定位是清除還是置位。
如果您的任務是在任何其他基數(例如基數10 =十進制)中顯示數字,則必須進行復雜的計算才能找出形成十進制格式「69」的特定數字'6'
和'9'
。
的兩個電源的任何基地是有點簡單,因爲你只需要抽取位(例如組十六進制基數爲16的每一個數字是價值正是4位部分,請注意45h
是二進制0100
( 4)和0101
(5)。但是你仍然需要計算一組比特。
只有二進制基2輸出基本上準備好打印,因爲這是計算機如何在寄存器和內存中存儲數字整數值的本地方式。
這絕對是至關重要的,你體會到什麼是位,這是什麼意思是al
是8位重gister和ax
是16位寄存器,ah
是上的ax
8位,等等...如果你不明白的數學如何二進制的作品,這些值是如何在位進行編碼,你將很難用很簡單大會任務,就像這個一樣。
這就是爲什麼我還沒有在這裏添加任何代碼,因爲你需要先計算出你的數學,要充分了解什麼"base N" encoding of value手段。
在您瞭解計算機的工作原理之後,您很可能能夠快速檢查一些按位轉換或測試等指令,並執行位檢查+輸出0/1到屏幕循環。這是非常簡單的任務,當你理解它。編輯:我決定給你更直觀的東西,我在「簡單的8位彙編程序」中寫了「顯示二進制8位值」。
這不是8086,但:
- 所述指令 「相同」(只是非常有限,而不是完整的8086)
- 寄存器完全不同的(4個8位通用A,B,C, D和兩個專用的PC和SP指針)
- 內存佈局完全不同(只有256字節的總內存,最後24字節是用於「輸出」顯示)
- 原理相同,如果你明白這一點,8086會看起來更容易,更強大,更容易編碼(更多說明)。
把下面的代碼到網頁:http://schweigi.github.io/assembler-simulator/
並使用「步驟」被指令慢慢去指令,並觀看了「記憶」和「註冊」右看看,指令做什麼意見(你可以使用x86指令參考指南來閱讀指令應該做什麼,我認爲所有的描述都適合這個簡單的彙編程序(雖然有些標誌並不是100%正確,但是你不會注意到並且從開始就能更好地學習8086指令) )。
; init input values
MOV A, 0x45 ; A = 45h (this ASM needs "0x" for hexa)
MOV D, 240 ; point to output display after last digit
MOV C, 8 ; 8 chars (representing bits) to output
print_loop:
; convert lowest bit of A into ASCII digit '0' or '1'
MOV B, A ; copy of A (to preserve A value)
AND B, 1 ; extract lowest bit of A (B = 0 or 1)
ADD B, '0' ; turn the value 0/1 into ASCII '0'/'1'
; display '0' or '1' to "Output" window
MOV [D], B ; write the digit to output
DEC D ; update output pointer
; shift all bits in A to right by 1 position
SHR A, 1
; create space after 4 bits displayed
CMP C, 5 ; 8-3 = 5, fourth DEC is below (in future)
JNE .no_space
DEC D ; skip one position in output
.no_space:
; loop until 8 bits are displayed
DEC C ; counter of bits
JNZ print_loop ; repeat until C becomes 0
; stop simulator
HLT
然後你可以考慮如何把它變成8086版本。
我建議把循環邏輯從最高位轉到8086,因爲你可以使用更多的指令,比如adc
(例如你可以試圖弄清楚,結果是mov dl,24
adc dl,dl
...在shl
之後它可能相當有趣)。然後您可以通過int 21h,2
直接輸出數字(如果您將邏輯反轉爲從左到右測試位)。
或者您可以保持相同的邏輯,並將ASCII數字從最後存儲到內存緩衝區(確保您有足夠大的緩衝區),並用單個打印它int 21h, 9
。
或...如何計算相同的結果有100萬種其他方法(輸出爲從原始值45h
屏幕「0100 0101」ASCII碼數字)。只有在正確的地點和時間輸出正確的號碼,只要你的結果是正確的,你如何計算它並不重要。
不知道你的彙編程序是什麼以及它是如何編譯的,但是我的程序將從'mov al,45'編譯指令加載到'al'(不是'ax')值'45'(不是'69') 。 (如果你不小心錯過了'69'來自哪裏,那麼'45h == 69')。如果您的彙編程序支持源代碼中的二進制格式化,您的評論將會是'mov ax,69'或'mov ax,45h'或'mov ax,0b01000101'。無論哪種方式,8086的結果機器碼都是'b8 45 00',源碼的格式不重要。 – Ped7g
我忘了一件事。 ASCII中的'0x45'是'E',而不是numlock。在鍵盤掃描碼中,0x45是「numlock」(當你直接從BIOS中斷或鍵盤設備讀取掃描碼時,它們被轉換成ASCII字符之前)。「Numlock」沒有任何ASCII字符分配,它是特殊的IBM PC密鑰,它改變了鍵盤讀取的行爲,而ASCII是第一次廣泛傳播的7位字母編碼,在ASCII之前,基本上每臺計算機都有不同的編碼字符串。 – Ped7g
有沒有簡短的命令可以在屏幕上顯示二進制等值?使用dos中斷? –