我正在做一个将decmial数字数组转换为二进制数组的项目 在汇编emu8086中,我知道如何做到这一点,但我需要更多帮助理解汇编中的数组,想法是取每个数字并将其转换为二进制,然后添加表示来获得结果
arrayD 1 2 3 4
1->1000-> binary1
2->200 -> binary2
3->30 -> binary3
4-> binary4
add binary1,binary2,binary3,binary4
用汇编语言可行吗?
答案 0 :(得分:0)
以下是您的问题的解决方案,只需在EMU8086中进行复制粘贴并运行,完全注释以帮助您理解,它需要将一位数字存储在一个数组中,然后将每个数字乘以当时的幂(0。 .n,从右到左),并将这些数字存储在第二个数组中,最后显示所有内容(原始数组,新数组和总和):
.model small
.stack 100h
.data
arr1 dw 1,5,2,4,3 ;ARRAY OF ONE DIGIT NUMBERS.
arr2 dw 5 dup(?) ;ARRAY FOR CONVERTED NUMBERS.
len dw 5 ;LENGTH OF ARRAYS.
tot dw ? ;SUM OF ALL CONVERTED NUMBERS.
msj1 db 'The first array is:',13,10,'$'
msj2 db 'The resulting array is:',13,10,'$'
msj3 db 'The total sum is:',13,10,'$'
buffer db 6 dup(?) ;USED TO CONVERT NUMBERS TO STRING.
linbrk db 13,10,'$' ;LINE BREAK.
.code
start:
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;TASKS.
call process_arrays
call sum_array
call clear_screen
call display_arr1
call display_arr2
call total_sum
;WAIT FOR ANY KEY.
mov ah, 7
int 21h
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;-----------------------------------------
;MULTIPLY EACH NUMBER IN ARRAY1 BY 10^?, AND
;STORE THE RESULT IN ARRAY2. THE LAST NUMBER
;IS MULTIPLIED BY 10^0, THE PREVIOUS NUMBER
;IS MULTIPLIED BY 10^1, AND SO ON, EXAMPLE:
; ARR1 = [ 1,5,2,4,3 ].
;PROCESS = 3 * 10^0
; 4 * 10^1
; 2 * 10^2
; 5 * 10^3
; 1 * 10^4
; ARR2 = [ 10000,5000,200,40,3 ].
process_arrays proc
;INITIALIZATIONS.
mov cx, len ;LENGTH OF ARRAYS.
shl cx, 1 ;CX*2, NECESSARY BECAUSE EVERY NUMBER IS 2 BYTES LONG.
mov si, offset arr1 ;SI POINTS TO FIRST NUMBER.
add si, cx ;NOW SI POINTS BEYOND THE LAST NUMBER.
sub si, 2 ;NOW SI POINTS TO THE LAST NUMBER.
mov di, offset arr2 ;DI POINTS TO FIRST POSITION.
add di, cx ;NOW DI POINTS BEYOND THE LAST POSITION.
sub di, 2 ;NOW DI POINTS TO THE LAST POSITION.
mov cx, len ;REVERSE COUNTER (TO KNOW WHEN TO FINISH).
mov bp, 0 ;FIRST POWER OF 10: 10^0.
converting:
;CALCULATE 10^?.
cmp bp, 0
je first_time ;SPECIAL CASE: 10^0.
mov ax, 10
mul bp ;AX * BP = 10*BP (10*1, 10*10, 10*100, 10*1000).
mov bp, ax ;STORE RESULT OF MUL (AX) IN BP.
jmp not_first_time ;THIS JUMP IS TO SKIP MOV BP, 1.
first_time:
mov bp, 1 ;10^0 = 1.
not_first_time:
;MULTIPLY CURRENT NUMBER BY 10^?.
mov ax, [ si ] ;AX = CURRENT NUMBER.
mul bp ;AX * BP (CURRENT_NUMBER * 10^?).
;STORE RESULT IN THE OTHER ARRAY.
mov [ di ], ax
;MOVE TO NEXT POSITION IN ARRAYS. WE GO BACKWARDS BECAUSE WE MOVE
;FROM THE LEAST SIGNIFICANT DIGIT TO THE MOST (FROM RIGHT TO LEFT).
sub si, 2 ;MINUS 2 BECAUSE EACH NUMBER
sub di, 2 ;IS TWO BYTES LONG (DW).
loop converting ;CX--. IF (CX > 0) JUMP.
ret
process_arrays endp
;-----------------------------------------
;SUM ALL NUMBERS IN ARRAY2, EXAMPLE:
; ARR2 = [ 10000,5000,200,40,3 ].
;PROCESS = 10000 + 5000 + 200 + 40 + 3 = 15.243.
sum_array proc
mov si, offset arr2
mov cx, len ;REVERSE COUNTER.
mov ax, 0 ;TOTAL.
sums:
add ax, [ si ] ;SUM CURRENT NUMBER.
add si, 2 ;NEXT NUMBER IN ARRAY (2 BECAUSE NUMBER IS DW).
loop sums ;CX--. IF (CX > 0) JUMP.
mov tot, ax
ret
sum_array endp
;-----------------------------------------
display_arr1 proc
;DISPLAY MESSAGE.
mov dx, offset msj1
call printf
;DISPLAY NUMBERS.
mov si, offset arr1
mov cx, len
displ_a1:
mov ax, [ si ] ;GET CURRENT NUMBER.
push cx ;PRESERVE COUNTER (IT WILL BE MODIFIED).
push si ;PRESERVE POINTER (IT WILL BE MODIFIED).
;CONVERT CURRENT NUMBER TO STRING.
mov si, offset buffer ;PARAMETER FOR NUMBER2STRING.
call number2string ;CONVERT AX IN STRING POINTED BY SI.
;DISPLAY STRING.
mov dx, offset buffer ;STRING TO DISPLAY.
call printf
mov dx, offset linbrk ;LINE BREAK.
call printf
pop si ;RESTORE POINTER.
pop cx ;RESTORE COUNTER.
add si, 2 ;NEXT NUMBER IN ARRAY (2 BECAUSE NUMBER IS DW).
loop displ_a1 ;CX--. IF (CX > 0) JUMP.
ret
display_arr1 endp
;-----------------------------------------
display_arr2 proc
;DISPLAY MESSAGE.
mov dx, offset msj2
call printf
;DISPLAY NUMBERS.
mov si, offset arr2
mov cx, len
displ_a2:
mov ax, [ si ] ;GET CURRENT NUMBER.
push cx ;PRESERVE COUNTER (IT WILL BE MODIFIED).
push si ;PRESERVE POINTER (IT WILL BE MODIFIED).
;CONVERT CURRENT NUMBER TO STRING.
mov si, offset buffer ;PARAMETER FOR NUMBER2STRING.
call number2string ;CONVERT AX IN STRING POINTED BY SI.
;DISPLAY STRING.
mov dx, offset buffer ;STRING TO DISPLAY.
call printf
mov dx, offset linbrk ;LINE BREAK.
call printf
pop si ;RESTORE POINTER.
pop cx ;RESTORE COUNTER.
add si, 2 ;NEXT NUMBER IN ARRAY (2 BECAUSE NUMBER IS DW).
loop displ_a2 ;CX--. IF (CX > 0) JUMP.
ret
display_arr2 endp
;-----------------------------------------
total_sum proc
;CONVERT SUM TO STRING.
mov ax, tot ;PARAMETER FOR NUMBER2STRING (NUMBER TO CONVERT).
mov si, offset buffer ;PARAMETER FOR NUMBER2STRING (DESTINATION STRING).
call number2string ;CONVERT AX IN STRING POINTED BY SI.
;DISPLAY MESSAGE.
mov dx, offset msj3
call printf
;DISPLAY STRING.
mov dx, offset buffer ;STRING TO DISPLAY.
call printf
ret
total_sum endp
;-----------------------------------------
;PARAMETER : DX POINTING TO '$' FINISHED STRING.
printf proc
mov ah, 9
int 21h
ret
printf endp
;-----------------------------------------
clear_screen proc
mov ah, 0
mov al, 3
int 10H
ret
clear_screen endp
;------------------------------------------
;CONVERT A NUMBER IN STRING.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (STR).
;PARAMETERS : AX = NUMBER TO CONVERT.
; SI = POINTING WHERE TO STORE STRING.
number2string proc
;FILL BUFFER WITH '$' (NECESSARY TO DISPLAY).
push si ;PRESERVE POINTER (IT WILL BE MODIFIED).
call dollars ;FILL BUFFER WITH '$' (NECESSARY TO DISPLAY).
pop si ;RESTORE POINTER.
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.
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
number2string endp
;------------------------------------------
;FILLS VARIABLE WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
;PARAMETER : SI = POINTING TO STRING TO FILL.
dollars proc
mov cx, 6
six_dollars:
mov bl, '$'
mov [ si ], bl
inc si
loop six_dollars
ret
dollars endp
end start
我对array1(1,5,2,4,3)中的数字进行了硬编码,您可以更改此数字(但请注意,总和不得超过65535)。这是做什么的(例子):
ARRAY1 = [ 1,5,2,4,3 ].
PROCESS = 3 * 10^0
4 * 10^1
2 * 10^2
5 * 10^3
1 * 10^4
ARRAY2 = [ 10000,5000,200,40,3 ].
SUM = 15243
我不确定是否需要其他进程:将每个数量的array2转换为二进制格式并再次显示,请告诉我。
答案 1 :(得分:-1)
model small
.stack 100h .data result db ?
array1 db 10,20,30,40
.code start:
movax,@data
movds,ax
movsi,offset array1 movcx,lengthof array1
mov al,0 L1: add al,[si] incsi
Loop L1
movresult,al
movdx,offset result
mov ah,9
int 21h
mov ah,4ch int 21h
end start