'Output array of binary digits as a decimal number in NASM
I have a program that can add two arrays of binary numbers
I'm sorry, I'm not very good at asm
I can draw the conclusion myself, but to understand how to convert an array to a number, I don’t really understand how to do it
example:
section .text
global _start
_start:
mov esi, 0
mov ecx, len_arr_1
_add_two_array:
mov eax, 0
add al, [array_1 + esi]
add al, [array_2 + esi]
inc esi
mov [res + esi], ax
loop _add_two_array
mov esi, len_res - 1
_check:
Call update
dec esi
cmp esi, -1
jne _check
jmp output_set
update:
mov ebx, 2
cmp [res + esi], bl
jge return
ret
return:
sub [res + esi], bl
mov ebx, 1
add [res + esi - 1], bl
ret
output_set:
mov esi, 0
mov ecx, len_res
output:
push ecx
mov ecx, [res + esi]
inc esi
add ecx, 48
mov [msg], ecx
mov edx, msg_len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
pop ecx
loop output
exit:
nop
mov eax, 1
mov ebx, 0
int 80H
section .data
array_1 db 1, 1, 0
len_arr_1 equ $ - array_1
array_2 db 0, 1, 1
len_arr_2 equ $ - array_2
res db 0, 0, 0, 0
len_res equ $ - res
msg db '', 0xa
msg_len equ $ - msg
```
output: 1010 // need 10
how to display the resulting answer by converting it to a decimal number?
Solution 1:[1]
You throw un-commented asm code at us without any description what with what and how it does or does not. Most of us will not bother to look further.
You should clarify for example what your array represents Is it bigint or something else? like fixed point, floating point ... Is it MSB first or last?
Here few things I noticed just by quick look without any deeper analysis (Assuming unsigned "big" int):
I do not see any carry propagation during long num addition
Only the first addition (lowest bit/word) should use
addand all others should beadc!!! or all areadcif you clear carry flag before addition loop.your input is array of BYTEs and output is array of WORDs ?
That makes no sense and even if it is then you inconsistently update
esias you use it for both BYTEs and WORDs at the same time while incrementing only by 1. If not then your target digits overlap as you writeaxso depending on MSB first/last order you might overwrite already computed digits...Your test case is wrong due to previous bullets !!!
You know
110b + 011b = 1001bhowever without the carry propagation from #1 you got101bwrongly interpreted due #2 as1010b...You never convert binary to decadic
Now you should convert base which you do not do anywhere. For integers That is done by dividing the number by printing base (10) and printing the remainders in reverse order. So if your number is not too big convert your result array to single register value (using bitshifts and or) and then convert to decadic string...
1001b -> 1<<3 | 0<<2 | 0<<1 | 1<<0 = 9 // conversion to single register 9 / 10 = 0 + remainder 9 -> "9" // divisionIf the result would be
1010bit would be:1001b -> 1<<3 | 0<<2 | 1<<1 | 0<<0 = 10 // conversion to single 10 / 10 = 1 + remainder 0 -> "0" // division 1 / 10 = 0 + remainder 1 -> "10" // divisionIf the number is for examle 123:
123/10 = 12 remainder 3 -> "3" 12 /10 = 1 remainder 2 -> "23" 1 /10 = 0 remainder 1 -> "123"In case your array is big (does not fit into single register) you have to implement bignum division too ...
You are failing in many things at once !!! You should focus on single stuff/task not all bugs together ... I would start with printing some register hardcoded value in binary first (ignore rest of code), then coumulate array to such value, and only then try addition...
Here is my old lib for printing numbers to strings in NASM I wrote decades ago (just digged it out of my archive so you have some inspiration):
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; txtnum: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
txtnum:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;.hex16 num ax >> string hex16 [cs:si], si=end of string adress at zero
;.dec16 num ax >> string dec16 [cs:si], si=end of string adress at zero
;.dec32 num eax >> string dec32 [cs:si], si=end of string adress at zero
;.txt32 num eax << string dec32 [cs:si], si=end of string adress after zero
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.hex16 pusha
mov cx,4
.hex16l:rol ax,4
mov bl,al
and bl,15
add bl,'0'
cmp bl,'9'
jbe .hex16r
add bl,'A'-'0'-10
.hex16r:mov [cs:si],bl
inc si
loop .hex16l
mov [cs:si],cl
popa
add si,4
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dec16: push ax
push bx
push dx
mov bx,10
inc si
cmp ax,10
jb .dec16r
inc si
cmp ax,100
jb .dec16r
inc si
cmp ax,1000
jb .dec16r
inc si
cmp ax,10000
jb .dec16r
inc si
.dec16r:mov [cs:si],bh
push si
.dec16l:xor dx,dx
div bx
add dl,'0'
dec si
mov [cs:si],dl
cmp ax,0
jnz .dec16l
pop si
pop dx
pop bx
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.dec32: push eax
push ebx
push edx
mov ebx,10
inc si
cmp eax,10
jb .dec32r
inc si
cmp eax,100
jb .dec32r
inc si
cmp eax,1000
jb .dec32r
inc si
cmp eax,10000
jb .dec32r
inc si
cmp eax,100000
jb .dec32r
inc si
cmp eax,1000000
jb .dec32r
inc si
cmp eax,10000000
jb .dec32r
inc si
cmp eax,100000000
jb .dec32r
inc si
cmp eax,1000000000
jb .dec32r
inc si
.dec32r:mov [cs:si],bh
push si
.dec32l:xor edx,edx
div ebx
add dl,'0'
dec si
mov [cs:si],dl
cmp eax,0
jnz .dec32l
pop si
pop edx
pop ebx
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.txt32: push ebx
push ecx
push edx
mov eax,0
mov ebx,10
mov ecx,0
.txt32l:mov cl,[cs:si]
inc si
or cl,cl
jz .txt32e
cmp cl,'0'
jb .txt32e
cmp cl,'9'
ja .txt32e
sub cl,'0'
mul ebx
add eax,ecx
jmp .txt32l
.txt32e:or edx,edx
jz .txt32x
mov eax,-1
.txt32x:pop edx
pop ecx
pop ebx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; end. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
