NASM programming - Segmentation fault(core dumped) - arrays

My program is very simple. It takes two input from the user:
an array (only 2 digit positive numbers)
a 2-digit number to be searched
output: number of times the given no. occurs in array
sample
Enter the size of array
03
Enter a number
10
Enter a number
12
Enter a number
10
Enter the number to be searched
10
Your number appeared 02 times
everything seems to be working fine but this programs gives the error
0segmentation fault(core dumped)
Please help me solve this problem
enter code here
section .data
msg1: db "Enter the size of array",10
len1: equ $-msg1
msg2: db "Enter a number",10
len2: equ $-msg2
msg3: db "Enter the number to be searched :"
len3: equ $-msg3
msg4: db "Your entered number appeared "
len4: equ $-msg4
section .bss
temp: resb 1
array: resb 100
d1: resb 1
d0: resb 1
size: resb 1
num: resb 1
ele: resb 1
time: resb 1
section .text
global _start:
_start:
;Getting the size of array
mov eax,4
mov ebx,1
mov ecx,msg1
mov edx,len1
int 80h
mov eax,3
mov ebx,0
mov ecx,d1
mov edx,1
int 80h
mov eax,3
mov ebx,0
mov ecx,d0
mov edx,2
int 80h
sub byte[d1],48
sub byte[d0],48
mov al,byte[d1]
mov bl,10
mul bl
add byte[d0],al
mov al,byte[d0]
mov byte[size],al
mov byte[temp],al
mov ebx,array
reading:
push rbx ;preserves the value of ebx
mov eax,4
mov ebx,1
mov ecx,msg2
mov edx,len2
int 80h
mov eax,3
mov ebx,0
mov ecx,d1
mov edx,1
int 80h
mov eax,3
mov ebx,0
mov ecx,d0
mov edx,2
int 80h
sub byte[d1],48
sub byte[d0],48
mov al,byte[d1]
mov bl,10
mul bl
add byte[d0],al
mov al,byte[d0]
pop rbx
mov byte[ebx],al
add ebx,1
dec byte[temp]
cmp byte[temp],0
jg reading
mov eax,4
mov ebx,1
mov ecx,msg3
mov edx,len3
int 80h
mov eax,3
mov ebx,0
mov ecx,d1
mov edx,1
int 80h
mov eax,3
mov ebx,0
mov ecx,d0
mov edx,2
int 80h
sub byte[d1],48
sub byte[d0],48
mov al,byte[d1]
mov bl,10
mul bl
add byte[d0],al
mov al,byte[d0]
mov byte[ele],al
mov cl,byte[size]
mov byte[temp],cl
mov byte[time],0
search:
mov al,byte[ebx]
cmp byte[ele],al
jne nf
jmp f
mov cl,0
f: add ebx,1
add byte[time],1
dec byte[temp]
cmp byte[temp],cl
jg search
jmp next
nf:
add ebx,1
add byte[time],0
dec byte[temp]
cmp byte[temp],cl
jg sea rch
jmp next
next:
mov eax,4
mov ebx,1
mov ecx,msg4
mov edx,len4
int 80h
movzx ax,byte[time]
mov bl,10
div bl
mov byte[d1],al
mov byte[d0],ah
add byte[d0],48
add byte[d1],48
mov eax,4
mov ebx,1
mov ecx,d1
mov edx,1
int 80h
mov eax,4
mov ebx,1
mov ecx,d0
mov edx,1``
int 80h
mov eax,1
mov ebx,0
int 80h

global _start
section .text
_start:
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msglen
syscall
mov rax,0
mov rdi,0
mov rsi,no1
mov rdx,5
syscall
mov rax,1
mov rdi,1
mov rsi,msg1
mov rdx,msg1len
syscall
mov rax,0
mov rdi,0
mov rsi,no2
mov rdx,5
syscall
mov rax,[no1]
sub rax,30h
mov rbx,[no2]
sub rbx,30h
add rax,rbx
add rax,30h
mov [res],rax
mov rdx,2
syscall
mov rax,1
mov rdi,1
mov rsi,res
mov rdx,2
syscall
mov rax,60h
mov rdx,0
syscall
section .data
msg: db "Enter 1st Number",0x0a
msglen equ $ -msg
msg1: db "Enter 2st Number",0x0a
msg1len equ $ -msg1
msg2:db "Addition is==",0x0a
msg2len equ $ -msg2
section .bss
no1: resb 5
no2: resb 5
res: resb 15

Looking at the source, I noticed one thing. I think your 'search' loop goes out of bounds because you failed to initialize register cl; the instruction mov cl,0 is currently dead code; it is beneath an unconditional jump so it never ever gets executed.
But as I said earlier, when in doubt, use a debugger.

Related

Retrieve data from an array

So, basically I just want to display the first data from array which is userbalanceIndex1 from userbalanceIndex.
But I get an error which is
DEMO.ASM(29): Out of memory
29 line: mov bl,(userbalanceIndex +1)
Here is my code:
.model small
.stack 100H
.data
userbalanceIndex db usrbalance1, usrbalance2, usrbalance3, usrbalance4
usrbalance1 Db 1
usrbalance2 Db 9
usrbalance3 Db 6
usrbalance4 Db 0
.code
OUTPUT MACRO DIGIT
MOV AH, 02H
MOV DL, DIGIT
INT 21H
ENDM
main proc
MOV AX,#DATA
MOV DS,AX
mov al, userbalanceIndex
mov cx, 0
a:
inc userbalanceIndex
mov bl, (userbalanceIndex + 1)
loop a
OUTPUT bl
mov ah, 4ch
int 21h
main endp
end main

Swapping the first and last element in the array using assembly

segment .data
array: db 68,222,29,68,33,234,179,103,37,85
fmt: db ",%d",0
segment .text
extern printf
global asm_main
asm_main:
enter 0,0 ; setup routine
pusha
push dword 10
push dword array
call print_array
add esp,8
push dword 10
push dword array
swap_byte_first_last:
mov eax,[array]
mov edx,[array+9]
mov [array+9],eax
mov [array],edx
call print_array
; don't delete anything following this comment
popa
mov eax, 0 ; return back to C
leave
ret
segment .data
ListFormat db ",%u", 0
segment .text
global print_array
print_array:
enter 0,0
push esi
push ebx
xor esi, esi
mov ecx, [ebp+12]
mov ebx, [ebp+8]
xor edx,edx
mov dl,[ebx + esi]
mov eax,edx
call print_int
dec ecx
inc esi
print_loop:
xor edx,edx
mov dl,[ebx + esi]
push ecx
push edx
push dword ListFormat
call printf
add esp, 8
inc esi
pop ecx
loop print_loop
call print_nl
pop ebx
pop esi
leave
ret
%define A_ADDR [ebp+12]
%define B_ADDR [ebp+8]
%define A_VAL [eax]
%define B_VAL [ebx]
segment .text
global swap_byte
swap_byte:
enter 0,0
pusha
mov eax, A_ADDR
mov ebx, B_ADDR
mov dl,A_VAL
mov cl,B_VAL
mov [eax],cl
mov [ebx],dl
popa
leave
ret
This prints 85,44,37,100,33,234,179,103,37,68. The result should be 85,222,29,68,33,234,179,103,37,68.
I was able to swap first element (68) with the last element (85), but numbers 222,29,and 68 have changed to 44,37,and 100. What changes do I need to make with the codes in swap_byte_first_last? Other parts of the code were given.

Print an integer NASM

I'm trying to read 3 numbers from the user and I store them in an array then I show them using paul carter functions in NASM here is my code :
%include "asm_io.inc"
SECTION .bss
tab resb 3
SECTION .data
msg db "Un nombre :",10
SECTION .text
global main
main:
mov esi,tab
xor ecx,ecx
get_data:
mov eax,msg
call print_string
call read_int
mov [esi+ecx],eax
inc ecx
cmp ecx,3
jne get_data
call print_nl
xor ecx,ecx
mov edi,tab
print_data:
mov eax,[edi+ecx]
call print_int
inc ecx
cmp ecx,3
jne print_data
mov eax,1 ; exit code
int 0x80 ; call exit
The problem is that is doesn't execute print_data loop and it exit .
Just to be clear. Are these the changes you did? Even if the ECX register is not used as an input or output for a particular function it might still be used internally. That's what Michael meant with 'ecx is typically caller-saved'
%include "asm_io.inc"
SECTION .bss
tab resd 3
SECTION .data
msg db "Un nombre :",10,0
SECTION .text
global main
main:
mov edi,tab
xor ecx,ecx
get_data:
push ecx
mov eax,msg
call print_string
call read_int
mov [edi+ecx*4],eax
pop ecx
inc ecx
cmp ecx,3
jne get_data
call print_nl
mov esi,tab
xor ecx,ecx
print_data:
push ecx
mov eax,[esi+ecx*4]
call print_int
pop ecx
inc ecx
cmp ecx,3
jne print_data
mov eax,1 ; exit code
int 0x80 ; call exit

How do i print a unsigned array of numbers in assembly?

this is my code:
.model small
.stack 100h
.data
A db 2,-5,3,4,-8
N equ 5
.code
mov ax, #data
mov ds, ax
mov si,offset A
mov cl,1
start:
cmp cl,N
je sof
mov al,[si]
cmp al,[si+1]
jg change
jmp next
change:
mov ah,al
mov al,[si+1]
mov [si],ah
mov [si+1],al
jmp next
next:
inc si
inc cl
jmp start
sof:
mov ah,9
mov cx, offset A
int 21h
.exit
end
i get a weird out put a lot of weird characters :/
You need to add 30h to a number in range 0 through 9 in order to display an ascii character. To display a character, use
;al = digit to display
mov dl,al
add dl,030h
mov ah,02 ;display character (in dl)
int 21h

Finding Smallest Number in NASM 2D Array

So I have the following code that worked for finding the LARGEST number in any given n by m matrix.
segment .bss
num: resw 1 ;For storing a number, to be read of printed....
nod: resb 1 ;For storing the number of digits....
temp: resb 2
matrix1: resw 200
m: resw 1
n: resw 1
i: resw 1
j: resw 1
buff resb 4
segment .data
msg1: db "Enter the number of rows in the matrix : "
msg_size1: equ $-msg1
msg2: db "Enter the elements one by one(row by row) : "
msg_size2: equ $-msg2
msg3: db "Enter the number of columns in the matrix : "
msg_size3: equ $-msg3
msg4: db "The smallest Number is... : "
msg_size4: equ $-msg4
tab: db 9 ;ASCII for vertical tab
new_line: db 10 ;ASCII for new line
segment .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, msg_size1
int 80h
mov ecx, 0
call read_num
mov cx, word[num]
mov word[m], cx
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, msg_size3
int 80h
mov ecx, 0
call read_num
mov cx, word[num]
mov word[n], cx
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, msg_size2
int 80h
;Reading each element of the matrix........
mov eax, 0
mov ebx, matrix1
mov word[i], 0
mov word[j], 0
i_loop:
mov word[j], 0
j_loop:
call read_num
mov dx , word[num]
;eax will contain the array index and each element is 2 bytes(1 word) long
mov word[ebx + 2 * eax], dx
inc eax ;Incrementing array index by one....
inc word[j]
mov cx, word[j]
cmp cx, word[n]
jb j_loop
inc word[i]
mov cx, word[i]
cmp cx, word[m]
jb i_loop
; read out matrix code
xor esp, [matrix1]
; esp initialized to first element in array, & is first smallest value
;Loop through the matrix, check each number if its
;larger than the first number in the array. AT the end print said number.
;Reading each element of the matrix.(Storing the elements in row major order).......
mov ebp, 0
mov edi, matrix1
mov esp, 0
mov word[i], 0
mov word[j], 0
i_loop2:
mov word[j], 0
j_loop2:
;eax will contain the array index and each element is 2 bytes(1 word) long
mov dx, word[edi+2*ebp] ;
mov word[num] , dx
cmp esp, [num] ; compares current smallest number with current element iterated.
jle skip
mov esp, [num] ; stores new smallest number
mov esi, ebp ; Stores pointer to the smallest element (never used..?)
skip:
inc ebp
inc word[j]
mov cx, word[j]
cmp cx, word[n]
jb j_loop2
inc word[i]
mov cx, word[i]
cmp cx, word[m]
jb i_loop2
;outut
mov eax, 4
mov ebx, 1
mov ecx, msg4
mov edx, msg_size4
int 80h
mov ecx, 0
mov eax, 4 ; system_write
mov ebx, 1 ; stdout
mov ecx, esp ; move smallest element to accumulator
add ecx, 48 ; convert to ascii representation
mov [buff], ecx ; move to memory
mov ecx, buff
mov edx, 4 ; size, 4 bytes
int 80h
exit:
mov eax, 1
mov ebx, 0
int 80h
;Function to read a number from console and to store that in num
read_num:
pusha
mov word[num], 0
loop_read:
mov eax, 3
mov ebx, 0
mov ecx, temp
mov edx, 1
int 80h
cmp byte[temp], 10
je end_read
mov ax, word[num]
mov bx, 10
mul bx
mov bl, byte[temp]
sub bl, 30h
mov bh, 0
add ax, bx
mov word[num], ax
jmp loop_read
end_read:
popa
ret
I've identified the problem is likely mov esp, 0 but without that line the results are even worse, with it the answer is always '0'. Without it it result in either nothing or gibberish.
Again, it original works for finding the LARGEST number but now I want to find the smallest, logically this should've meant just changing jge to jle but either it keeps zero (likely because of mov esp, 0 ) or gibberish if I try to make it something else?
How can I fix this so I do find the smallest number with the least amount of changes? The code did originally work albeit only after significant trial and error almost at random with my fiddling.
Additionally the gibberish outputted is this: â½µÿ
If I remove mov esp, 0 but keep it as jge, it still works for the LARGEST number, but if I switch it to jle, it outputs â½µÿ. This makes zero sense.

Resources