使用汇编程序 8086 显示 table 的总和
Displaying the sum of a table using assembler 8086
我正在编写一些代码,允许我对 table 求和,然后使用汇编语言显示其结果。这是我到目前为止的想法:
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
可以通过以下方式添加 BYTE 序列:
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 BYTE 值。问题是您的 "print" 函数不起作用,因为函数 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
中的数字,您必须先将其转换为字符串。
[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
我对您的代码进行了一些更改,并从另一个答案中窃取了 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
将 ax 中的任何数字转换为字符串,并将结果存储在变量 resultat
中(因为它在数据段中定义)。
我正在编写一些代码,允许我对 table 求和,然后使用汇编语言显示其结果。这是我到目前为止的想法:
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
可以通过以下方式添加 BYTE 序列:
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 BYTE 值。问题是您的 "print" 函数不起作用,因为函数 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
中的数字,您必须先将其转换为字符串。
[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
我对您的代码进行了一些更改,并从另一个答案中窃取了 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
将 ax 中的任何数字转换为字符串,并将结果存储在变量 resultat
中(因为它在数据段中定义)。