頁:
[1]
2
[組合語言] 讀出電腦現在有插幾條memory
大家好目前我想要做的事是能讀出電腦memory的資料 然後顯示出結果
只是當它讀完第一條memory然後顯示出來後
它就沒辦法再讀第二條
程式就掛在那邊沒辦法繼續了
所以想問說是哪裡有問題
我該如何改寫
謝謝
這是我改寫的code
.model small
.586
.stack 100h
.data
WELCOME_LINE DB 'Read Memorys','
CHANGE_LINE1 DB 10,13,'
;換行
CHANGE_LINE2 DB 10,13,'
;換行
SPACE DB 0,'
END_PROGRAM DB 'Type Enter to end the program','
SMBASE DW 0F040h; SMB_BASE address
MAX_LEN DB 3
ACT_LEN DB ?
BUFFER DB 3 dup(?)
TEMP DB 0
.code
start:
;initilization
mov ax,@data
mov ds,ax
;Print WELCOME_LINE
mov ah,09h
lea dx,WELCOME_LINE
int 21h
call changeLine1
xor cx,cx ;cx for counter
call CheckSmbusReady
call ReadSpdData1
call changeLine1
call ReadSpdData2
call changeLine1
;Print END_PROGRAM
mov ah,09h
lea dx,END_PROGRAM
int 21h
;
;mov ah,0ah
;lea dx,MAX_LEN
;int 21h
mov ax,4c00h ;return 0
int 21h
;==CheckSmbusReady==
CheckSmbusReady:
mov dx,SMBASE
in al,dx
mov ah,40h
cmp al,ah
jnz CheckSmbusReady
retn
;==CheckByteDoneStatus==
CheckByteDoneStatus:
mov dx,SMBASE
in al,dx
mov ah,42h
cmp al,ah
jnz CheckByteDoneStatus
retn
;==ReadSpdData1==
ReadSpdData1:
;set HST_STS
mov dx,SMBASE
mov al,0FFh
out dx,al
;set Slave Address
mov dx,SMBASE
add dX,04H
mov al,0A1h; for read SPD
out dx,al
;set HST_CMD to 00h
mov dx,SMBASE
add dX,03H
mov al,117
add al,cl
out dx,al
;set HST_D0 to 00h
mov dx,SMBASE
add dX,05H
mov al,00
out dx,al
;set HST_CNT 0x48 Byte Read
mov dx,SMBASE
add dx,02H
mov al,48h
out dx,al
call CheckByteDoneStatus
;print offset[]
mov dx,SMBASE
add dx,05h
in al,dx
mov TEMP,al
call hex2ascii
call printSpace
.if cl<=7
add cl,1
call ReadSpdData1
.elseif cl==8
call ChangeLine1
retn
.endif
retn
;==ReadSpdData2==
ReadSpdData2:
;set HST_STS
mov dx,SMBASE
mov al,0FFh
out dx,al
;set Slave Address
mov dx,SMBASE
add dX,04H
mov al,0A5h; for read SPD
out dx,al
;set HST_CMD to 00h
mov dx,SMBASE
add dX,03H
mov al,117
add al,cl
out dx,al
;set HST_D0 to 00h
mov dx,SMBASE
add dX,05H
mov al,00
out dx,al
;set HST_CNT 0x48 Byte Read
mov dx,SMBASE
add dx,02H
mov al,48h
out dx,al
call CheckByteDoneStatus
;print offset[]
mov dx,SMBASE
add dx,05h
in al,dx
mov TEMP,al
call hex2ascii
.if cl<=7
add cl,1
int 21h
.elseif cl==8
int 21h
retn
.endif
retn
;==hex2ascii===
hex2ascii:
xor ax,ax
mov al,TEMP
and al,0f0h
ror al,4
;.if al!=0
.if al>=00h && al <=09h
add al,30h ;add 30h,become ascii number
.else
add al,37h ;add 37h,become ascii alphabet
.endif
mov ah,02h
mov dl,al
int 21h
;.endif
mov al,TEMP
and al,0fh
.if al>=00h && al<=09h
add al,30h
.else
add al,37h
.endif
mov ah,02h
mov dl,al
int 21h
retn
;==changeLine1
changeLine1:
;Print CHANGE_LINE1
mov ah,09h
lea dx,CHANGE_LINE1
int 21h
retn
;==printSpace
printSpace:
mov ah,09h
lea dx,SPACE
int 21h
retn
;======end the program=========
end start
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div> 本帖最後由 scottcheng 於 2016-11-12 11:52 PM 編輯
(1) A1 應該是bank0 + read , A5 應該是bank 2 + read 是不是這個設錯了..
(2) mov al,117
add al,cl <--- cl 哪來的值? 我的認知妳是你想讀 117 + 0 ~ 117+7 對吧, 所以才讀spd1 時, 會再 add cl, 1 , 如果是, 妳第二次並沒有把 cl 歸 0 , 妳再 readspd1 至少還有 xor cx,cx
(3) 妳已經透過SMBASE+03h 送出你要讀的reg, 為什麼還要送 SMBASE+05h ? 送 0 出去
(4) 146 行 妳不是應該再 call 一次 read spd2 ? 而不是 int 21h
(5) 148 行 你直接 call int 21h 我不清楚ah當時是甚麼, 你最好弄清楚, spd1 和 spd2 寫法不同
我大概就單純看code 的結論, 你思考一下吧!
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div> 後來我是有一個想法是說
程式會掛在那邊可能是因為暫存器有存spd1的值在裡面
導致沒法繼續做spd2的事
所以想說如果把spd1印完後清掉空間再做spd2是不是就可以了 smbase 妳不是有填 ff 去 reset ? 我是不知道要不要做這個動作. 但很明顯, 我在 2f 寫的東西, 妳可以仔細看一看.. 光妳的程式寫法就兩套. 尤其3,4,5 這三點, 妳的code肯定有問題!
如果所講, 如果你覺得是因為 read spd1 有問題, 那你可以把 read spd1 先 mark 掉, 看注意妳在 call readspd1 之前有 xor cx, cx.. readsp2 並沒有..
ps: 我已經10年沒寫bios, 所以我只能看code 的邏輯, 妳先更正我在2f提到的問題, 在試驗一次, 如果你懷疑 readspd1 有問題, 把他mark掉, 直接 call readsp2
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div> 其實ReadSpdData1跟2是一樣的
只差在一個是mov al,0A1h 一個是0A5h
我有單獨拉只讀spd1跟2的
讀到有插卡的位置時就能正常顯示出資料
但是去讀沒有插卡的位置時 他就會掛在那邊 沒辦法繼續<br><br><br><br><br><div></div> 我是不知道你發生甚麼狀況. 但
102-106 和 144-148 明明就不一樣, 另外 145 cl 根本沒 初始化 . 你是從 8 開始
如果你還是覺得一模一樣, 那我也幫不上忙, 畢竟我沒你的環境, 也只能從你貼的code上去建議!
本帖最後由 willy80720 於 2016-11-14 08:13 PM 編輯
謝謝你的指導我有修改過一些地方了
那我現在改用的方式是 建兩個程式
改的地方就是76行的部分 1個是A1h 1個是A5h
那我自己也有跑過了 單獨個別跑這兩個程式 都沒問題
可是如果是依序跑的話(先跑A1的再跑A5的時候,或是先跑A5再跑A1的)
先執行的程式會正常顯示出我要的值 可是要接著跑下一個 程式就會掛在那邊
那現在的問題就卡在
為什麼沒辦法連續執行程式
.model small
.586
.stack 100h
.data
WELCOME_LINE DB 'Read Manufacture Data in Memory Spd in Memory Spd 75H to 7DH','
CHANGE_LINE DB 10,13,'
;??
SPACE DB 0,'
END_PROGRAM DB 'Type Enter to end the program','
SMBASE DW 0F040h; SMB_BASE address
MAX_LEN DB 3
ACT_LEN DB ?
BUFFER DB 3 dup(?)
TEMP DB 0
.code
start:
;initilization
mov ax,@data
mov ds,ax
;Print WELCOME_LINE
mov ah,09h
lea dx,WELCOME_LINE
int 21h
call changeLine
xor cx,cx ;cx for counter
call CheckSmbusReady
call ReadSpdData
call changeLine
;Print END_PROGRAM
mov ah,09h
lea dx,END_PROGRAM
int 21h
;
;mov ah,0ah
;lea dx,MAX_LEN
;int 21h
mov ax,4c00h ;return 0
int 21h
;==CheckSmbusReady==
CheckSmbusReady:
mov dx,SMBASE
in al,dx
mov ah,40h
cmp al,ah
jnz CheckSmbusReady
retn
;==CheckByteDoneStatus==
CheckByteDoneStatus:
mov dx,SMBASE
in al,dx
mov ah,42h
cmp al,ah
jnz CheckByteDoneStatus
retn
;==ReadSpdData==
ReadSpdData:
;set HST_STS
mov dx,SMBASE
mov al,0FFh
out dx,al
;set Slave Address
mov dx,SMBASE
add dx,04H
mov al,0A1h; for read SPD
out dx,al
;set HST_CMD to 00h
mov dx,SMBASE
add dx,03H
mov al,117
add al,cl
out dx,al
;set HST_D0 to 00h
mov dx,SMBASE
add dx,05H
mov al,00
out dx,al
;set HST_CNT 0x48 Byte Read
mov dx,SMBASE
add dx,02H
mov al,48h
out dx,al
call CheckByteDoneStatus
;print offset[]
mov dx,SMBASE
add dx,05h
in al,dx
mov TEMP,al
call hex2ascii
call printSpace
.if cl<=7
add cl,1
call ReadSpdData
.elseif cl==8
call ChangeLine
retn
.endif
retn
;==hex2ascii===
hex2ascii:
xor ax,ax
mov al,TEMP
and al,0f0h
ror al,4
;.if al!=0
.if al>=00h && al <=09h
add al,30h ;add 30h,become ascii number
.else
add al,37h ;add 37h,become ascii alphabet
.endif
mov ah,02h
mov dl,al
int 21h
;.endif
mov al,TEMP
and al,0fh
.if al>=00h && al<=09h
add al,30h
.else
add al,37h
.endif
mov ah,02h
mov dl,al
int 21h
retn
;==changeLine
changeLine:
;Print CHANGE_LINE
mov ah,09h
lea dx,CHANGE_LINE
int 21h
retn
;==printSpace
printSpace:
mov ah,09h
lea dx,SPACE
int 21h
retn
;======end the program=========
end start
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div> 37-40 改成
; read spd1
call CheckSmbusReady
mov cx, 0A100h
call ReadSpdData
call changeLine
; read spd2
call CheckSmbusReady
mov cx, 0A500h
call ReadSpdData
call changeLine
76
mov al, ch; for read SPD
101 插入
push cx
104 插入
pop cx
試試看...call int21h 我不確定他會不會動到 cx
目前試下來 第一個可以正常秀出結果
輪到第二個就掛在那邊 不會秀出結果 本帖最後由 willy80720 於 2016-11-15 10:33 PM 編輯
剛剛我一行一行試 看是從哪裡開始會掛在那邊
然後在read spd2的call CheckSmbusReady
程式就會掛在那邊了 call changeLine
; read spd1
call CheckSmbusReady
mov cx, 0A100h
call ReadSpdData
call changeLine
;xor cx,cx
; read spd2
call CheckSmbusReady
mov cx, 0A500h
call ReadSpdData
call changeLine至於為什麼smbus要加那些數值
我只能說我是拿別人的程式來用
也跑出我要的結果 所以就直接來用了不過我有看你貼的網站
裡面倒是有提到加那些數值的原因
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div> 其實簡單的來說就是我7樓的程式(讀A1h的程式)
如果連續重複執行兩次
第一次會正常顯示出值
第二次就會掛在那邊
我想解決為什麼會掛在那邊的原因 妳試看看, 如果在不行...沒實際環境, 妳給的條件只有停在那邊, 我也無法幫忙甚麼, 就這樣了
(1) 55-57 (理論只需要check host_busy , bit0)
mov ah,40h
cmp al,ah
jnz CheckSmbusReady
改成
test al, 01h
jz CheckSmbusReady
(2) 63 - (理論只需要check host_busy , bit0)
mov ah,42h
cmp al,ah
jnz CheckByteDoneStatus
改成
test al, 01h
jz CheckByteDoneStatus
(3) remark 85-88 (我是認為不需要做這個動作)
mov dx,SMBASE
add dx,05H
mov al,00
out dx,al
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div> scottcheng 發表於 2016-11-16 03:12 AM static/image/common/back.gif
妳試看看, 如果在不行...沒實際環境, 妳給的條件只有停在那邊, 我也無法幫忙甚麼, 就這樣了
(1) 55-57 (理 ...
你好 你說的實際環境是指甚麼?
我是在dos下執行我所build的exe檔 本帖最後由 chevylin0802 於 2016-11-16 10:31 AM 編輯
純DOS環境指的是DOS開機的方式
不管你是用早期MSDOS的哪一個版本都算
另一種則稱之為DOS模擬環境
這種則是指在Windows的環境下開啟出來的DOS模擬器
或稱DOS指令環境
純DOS環境的話可以完全排除其它各種源自於多工環境所延申出來的問題
但是
如果是Windows下的DOS環境
那麼IN/OUT指令要很小心使用
因為隨時可能被系統岔斷給中斷執行
等到系統中斷處理程序完成之後
你的程式執行的環境已經變了
而且照道理來講你的程式應該是要編成.com的檔案
並讓它的code segment的offset固定在100H的位置上
因為exe是一種含有特定執行檔表頭的可執行檔
而且通常它的程式碼一開始是要針對記憶體管理模式進行設置
程式的啟始要先針對CPU的CS,DS,ES,SS以及BP, DI, SI等暫存器進行規劃的
一般來講像是在多工作業系統裏面進行這種處理
是需要先進行NMI處理的
也就是需要先進行中斷遮罩
等到I/O的存取完全完成之後再重新打開
針對記憶體的控制或者查詢的動作來講
更需要注意到的是DMA控制器的部份
因為它會干擾到記憶體控制器的暫存器狀態
另外更重要的是在於要對I/O進行控制的基本觀念在於需要了解硬體
尤其是關於控制晶片的時序圖方面的問題
所以在以前寫BIOS的程式設計師其實都已經有能力可以成為硬體工程師
因為軔體設計是要軟硬體兼備的知識
頻譜分析儀以及高頻示波器更是軔體工程師的標準配備
這也是純軟體的工程師所搞不定的主要原因
CPU的時脈現在普遍都在2.0GHz以上
但DDR RAM卻沒有那麼快
更不用談到其它PCI/PCIe裝置的時脈
也因此
通常CPU與CPU之外的周邊最起碼都會有三個控制腳位
分別是interrupt, RO, RW
只要時序圖沒有顧好的時候
軟體就會當機
也因此通常即使是在OS Kernel的部份
都會在I/O動作的過程當中進行一定時間的延遲(尤其是採取polling的方式時更需要長一點時間的delay)
比如10 nano seconds ~ 50 nano seconds
而且必定需要先進行中斷遮罩
以避免有其它的硬體中斷發生所產生的干擾
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div> chevylin0802 發表於 2016-11-16 10:19 AM static/image/common/back.gif
純DOS環境指的是DOS開機的方式
不管你是用早期MSDOS的哪一個版本都算
那這樣我是該在哪裡加延遲的動作?<br><br><br><br><br><div></div>
頁:
[1]
2