.model small
.資料
nizA db 1,2,3,4,5,6,7,8
nizB db 8 dup(?)
len equ 8
.代碼
主程式
mov si,0
mov di,0
mov cx,len
程式。
mov al,nizA[si] ;問題是在這里它總是將CDh存盤在AL中
cbw ;將AL轉換為AX,以便我可以進行除法。
mov bl,2 ;我想除掉的數字,所以我測驗它是否是偶數。
div bl ;溢位資訊
cmp ah,0
je next:
輸入。
mov dl,nizA[si].
mov nizB[di],dl
inc di
下一步。
增加si,2
回圈程式
結束
結束
我有這段代碼,是為我需要做的期末考試準備的,非常簡單。從給定陣列的偶數索引中找到奇數。因此,自然意味著我將SI增加2,并將該陣列元素放入AL。但是,無論陣列中的數字是什么,在AL中存盤的總是十六進制數字CD,如果它是按規定存盤的,我想做CBW來轉換為AX,并能用BL進行除法。
我現在只收到EMU 8086的錯誤資訊,說
除法錯誤 - 溢位。要手動處理這個錯誤,請改變中斷向量中INT 0的地址。 中斷向量表中INT 0的地址。
這肯定與CD號有關,我這里只有兩個問題
uj5u.com熱心網友回復:
你用cx加載了8,所以你的回圈將迭代8次。 但是你在每次迭代時都將si增加2,所以在前4次迭代后,你已經超過了nizA陣列的末端。
嘗試將mov cx, len替換為mov cx, len/2。
順便說一下,檢查al是否為奇數的一個更簡單和更有效的方法是做test al, 1,它根據al與1的位和來設定標志。
uj5u.com熱心網友回復:
"CD被存盤而不是1"
當一個DOS .EXE啟動時,DS段暫存器不會指向你的程式的.data部分! DS段暫存器指向ProgramSegmentPrefix,又稱PSP。這個256位元組的區域是DOS保存關于正在運行的程式的一些重要資料的地方,在這里你可以檢索到程式的命令列,偏移地址為128。
當你的代碼運行時,你發現了CDh這個值,因為它剛好是PSP中的第一個位元組。它是int 20h指令的操作碼,該指令總是開始于PSP。
你需要寫的是:
.code
主程式
mov ax, @data
mov ds, ax
"溢位(很可能是因為CD太高了,但我還是把數字除掉了,它們只會變小,所以它不會有意義)"
事實上,它確實有意義。因為您正在使用CBW將紅利擴展到AX,并且因為AL中的值錯誤地是CDh,AX中的新值成為FFCDh。當你的代碼再除以2(使用mov bl, 2 div bl)時,商要比能存盤在除法專用商暫存器AL的值大得多。這就是為什么你會出現 "除法錯誤"。
解決方案
mov ax, @data
mov ds, ax
mov si, 0
mov di, 0
mov cx, len/2
程式。
mov al, nizA[si]
mov ah, 0 ; 對于UNSIGNED除法,不要使用CBW
mov bl, 2
div bl
cmp ah, 0 ; 剩余部分
je next
mov dl, nizA[si] ; 重新加載
mov nizB[di], dl
inc di
下一步。
增加 si, 2
回圈程式
- 避免了除法而采用
TEST的解決方案,也增加了一些額外的改進:
mov ax, @data
mov ds, ax
xor si, si ; 比 "mov si, 0 "更好的是將一個暫存器清零。
xor di, di ; 同上
程式。
mov al, nizA[si]
測驗al, 1
jz IsEven
mov nizB[di], al ; 只存盤 "奇數 "值
inc di
IsEven:
add si, 2 ; 下一個'偶數'索引
cmp si, len
jb程式
看到TEST AL, 1對AL暫存器是無損的,因此你不需要在寫入nizB陣列之前重新加載值嗎?
還要注意,你并不總是需要一個單獨的回圈計數器。這里我使用了源陣列的索引來代替。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/320390.html
標籤:
上一篇:我如何在匯編中正確操作堆疊?
