2016-11-23 65 views
1

我正在編寫一些代碼,它允許我總結一個表格,然後使用匯編語言顯示其結果。這裏是我想出迄今:使用匯編程序顯示錶格的總和8086

data segment 
    tab  db 9 dup(3 5 8 4 7 1 6 7 0) 
    resultat db ? 
data ends 

code segment 
    xor di, di 
    mov cx, 9 
Prog: 
    mov al, tab[di] 
    add ax, al 
    inc di 
loop prog 
    mov resultat ,ax 
    mov ah, 09h 
    int 21h 
end code 
+0

你使用什麼彙編器? MASM,TASM,FASM,NASM ......? – zx485

+0

Ela,你的結果在'ax'中是二進制的,你必須將它轉換爲字符串來顯示它。如果你顯示'ax',你會在屏幕上看到奇怪的字符。 –

+0

am使用emu 8086 –

回答

4

我做在你的代碼的一些變化,並從另一個答案偷PROC number2string(充分的意見,幫助您瞭解):

data segment 
tab db 3,5,8,4,7,1,6,7,0 ;ARRAY OF NUMBERS. 
resultat db '  $' ;STRING WITH 5 CHARS. 
data ends 
code segment 
mov ax,@data ;INITIALIZE 
mov ds,ax  ;DATA SEGMENT. 

xor di,di 
mov cx,9 
xor ax,ax  ;CLEAR THE SUM ACCUMULATOR. 
Prog: 
add al,tab[di] 
inc di 
loop prog  

call number2string ;CONVERT AX TO STRING IN RESULTANT. 

lea dx,resultat 
mov ah,09h 
int 21h 

mov ax, 4c00h 
int 21h  ;TERMINATE PROGRAM. 

;------------------------------------------ 
;NUMBER TO CONVERT MUST ENTER IN AX. 
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE 
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE 
;ORDER TO CONSTRUCT STRING. 
;THE STRING IS STORED IN VARIABLE "RESULTAT". 

proc number2string 
    mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10. 
    mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS. 
cycle1:  
    mov dx, 0 ;NECESSARY TO DIVIDE BY BX. 
    div bx ;DX:AX/10 = AX:QUOTIENT DX:REMAINDER. 
    push dx ;PRESERVE DIGIT EXTRACTED FOR LATER. 
    inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED. 
    cmp ax, 0 ;IF NUMBER IS 
    jne cycle1 ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS. 
    lea si, resultat 
cycle2: 
    pop dx   
    add dl, 48 ;CONVERT DIGIT TO CHARACTER. 
    mov [si], dl 
    inc si 
    loop cycle2 

    ret 
endp 
;------------------------------------------ 

end code 

的PROC number2string任何數字轉換爲字符串中的斧頭和商店變量resultat中的結果(因爲它在數據段中定義)。

+0

非常感謝你 –

+0

完成,但我不明白'lea si,resultat'它做了什麼 –

+0

@ElaHidri,它使'si'指向'resultat',就像你的'tab [di]'。 –

2

添加一個字節序列可以做到這樣:

code segment 
    xor ax, ax  ; clear AX 
    xor dx, dx  ; accumulator for result value 
    lea si, tab  ; SI = address of TAB 
    mov cx, 9  ; LEN of TAB in BYTEs 
Prog: 
    lodsb   ; AL = BYTE PTR [SI] and increment SI 
    add dx, ax  ; add 0:AL to DX 
loop prog   ; decrements CX and jumps if not 0 
    mov resultat, dx ; mov DX=accumulator to variable 
    ; PROBLEM !!! 
    mov ah, 09h  ; !!! prints string and not a number !!! 
    int 21h 
    ; PROBLEM END!!! 
    mov ah, 4Ch  ; exit program 
    int 21h   
end code 

該代碼將在DX CX = 9個字節值。問題是,你的「打印」功能不起作用,因爲功能AH=09h of INT 21h打印在DS的字符串:DX,而不是一個數字:

Int 21/AH=09h - DOS 1+ - WRITE STRING TO STANDARD OUTPUT 
--- 
AH = 09h 
DS:DX -> '$'-terminated string 
--- 
Return: 
AL = 24h (the '$' terminating the string, despite official docs which states that nothing is returned) (at least DOS 2.1-7.0 and 
NWDOS) 

所以打印在DX數你必須將它轉化成一個字符串第一。

+0

我怎樣才能將它轉換爲字符串 –

+2

已經有幾個SO覆蓋該主題的答案:[this](http://stackoverflow.com/a/40505492/1305969),[this](http://stackoverflow.com/a/39577676/1305969)和[this](http://stackoverflow.com/a/32102489/1305969)。我希望這能夠讓你解決這個問題。 – zx485

+0

非常感謝你 –

-2
[bits 16] 
[org 0x100] 

jmp _start 

_start: 
    mov cl, 0 
    mov ah, 0x0e 

_loop: 
    cmp cl, 10 
    je _end 

    mov al, byte cl 
    or al, 30h ;Convert number to char 
    int 0x10 

    ;Print a space 
    mov al, 0x20 
    int 0x10 

    inc cl 
    jmp _loop 

_end: 
    mov ax, 0x4c 
    int 0x21 
+0

歡迎來到SO!你應該總是解釋你的代碼你發佈 – rbr94

+0

thnx它不工作 –

+1

好的我會下一次 –