2016-11-09 77 views
4

我寫了一個非常簡單的代碼在asm x8086中,我正面臨一個錯誤。如果有人能夠幫助我做一個簡短的解釋,我將不勝感激。裝配8086 |一個數組的總和,打印多位數字

IDEAL 
MODEL small 
STACK 100h 
DATASEG 
; -------------------------- 
    array db 10h, 04h, 04h, 04h, 04h, 04h, 04h, 04h, 04h, 04h 
    sum db 0 
    ; -------------------------- 
CODESEG 
start: 
    mov ax, @data 
    mov ds, ax 
; -------------------------- 
    xor cx, cx 
    mov al, 0 
    mov bx, offset array 
StartLoop: 
    cmp cx, 10 
    jge EndLoop 
    add al, [bx] 
    add [sum],al 
    inc cx 
    inc bx 
    jmp StartLoop 
EndLoop: 
    mov ah, 09h 
    int 21h 

; -------------------------- 

exit: 
    mov ax, 4c00h 
    int 21h 
END start 
+2

注意該行:加al,[bx]其實是mov al,[bx] –

+0

我想在這裏簡要解釋一下:http://stackoverflow.com/help/how-to-ask(目前還不清楚你在問什麼)Plus對於彙編,它總是有助於指定你的目標平臺/操作系統來運行代碼,以及你使用什麼彙編器來編譯它(即使複製使用的命令行也不要猶豫,所以有時甚至可能有助於解決問題)。 – Ped7g

+0

我的意思是,很少有人會看看你的源代碼,並且有相同的環境,所以他們可以複製/粘貼它,編譯並查看你的問題。這裏的大多數人會利用他們的知識和經驗在他們的腦海中做一個「空轉」,爲了讓他們更容易,你應該提供每一個相關的細節(想象你自己閱讀你的問題, )。 – Ped7g

回答

2

隨着修正爲addmov被替換爲您的評論指出(注意行:加人,[BX]實際上是MOV人,[BX])但只是功能打電話給標籤EndLoop這是錯誤的!

您想要顯示總和,並且正在使用DOS打印功能。此功能09h需要DS:DX中沒有提供的指針!
即使你做了,你仍然必須在其文本表示中轉換總和號碼。

這裏的一個快速解決方案是讓自己滿意,並以單個ASCII字符的形式顯示結果。硬編碼的和是52,所以它是一個顯示字符:

EndLoop: 
    mov dl, [sum] 
    mov ah, 02h ;Single character output 
    int 21h 

; -------------------------- 

exit: 
    mov ax, 4c00h 
    int 21h 

一步,我們就可以顯示「52」:

mov al,[sum] 
mov ah,0 
mov dl,10 
div dl  ---> AL=5 AH=2 
add ax,3030h ---> AL="5" AH="2" 
mov dh,ah  ;preserve AH 
mov dl,al 
mov ah,02h 
int 21h 
mov dl,dh  ;restore 
int 21h 
1

我看不出有什麼錯誤可言,代碼將總結數組,顯示一些隨機sh * t,然後退出。

您可能想要顯示總和的結果嗎?

int 21h, ah=9將顯示'$'來自dx指向的內存的終止字符串。

所以,你需要兩樣東西,轉換數[sum]在年底通過'$'結尾的字符串,然後設置dx到轉換後的字符串是領先的int 21h

您可以嘗試從這裏提取number2string程序:https://stackoverflow.com/a/29826819/4271923

我會親自將它更改爲採取目標緩衝區的地址在si作爲另一個調用參數(即只是刪除從過程體內mov si,offset str)。就像這樣:

PROC number2string 
    ; arguments: 
    ; ax = unsigned number to convert 
    ; si = pointer to string buffer (must have 6+ bytes) 
    ; modifies: ax, bx, cx, dx, si 
    mov bx, 10 ; radix 10 (decimal number formatting) 
    xor cx, cx ; counter of extracted digits set to zero 
number2string_divide_by_radix: 
    ; calculate single digit 
    xor dx, dx ; dx = 0 (dx:ax = 32b number to divide) 
    div bx  ; divide dx:ax by radix, remainder will be in dx 
    ; store the remainder in stack 
    push dx 
    inc cx 
    ; loop till number is zero 
    test ax, ax 
    jnz number2string_divide_by_radix 
    ; now convert stored digits in stack into string 
number2string_write_string: 
    pop dx 
    add dl, '0' ; convert 0-9 value into '0'-'9' ASCII character encoding 
    ; store character at end of string 
    mov [si], dl 
    inc si 
    ; loop till all digits are written 
    dec cx 
    jnz number2string_write_string 
    ; store '$' terminator at end 
    mov BYTE PTR [si],'$' 
    ret 
ENDP 

然後在調用這個你EndLoop你需要添加到數據段numberStr DB 8 DUP (0)有分配的字符串一些內存緩衝區,並添加到代碼:

; load sum as 16b unsigned value into ax 
     xor ax,ax  ; ax = 0 
     mov al,[sum] ; ax = sum (16b zero extended) 
    ; convert it to string 
     mov si,OFFSET numberStr 
     call number2string 
    ; display the '$' terminated string 
     mov dx,OFFSET numberStr 
     mov ah,9 
     int 21h 
    ; ... exit ...