-2
        SYS_EXIT  equ 1
    SYS_READ  equ 3
    SYS_WRITE equ 4
    STDIN     equ 0
    STDOUT    equ 1

segment .data 

    msg db "Please enter a digit ", 0xA,0xD 
    len equ $- msg 

segment .bss

    number1 resb 2 
    number2 resb 2 
    result resb 1 
    result2 resb 1


segment .text 

    msg2 db "Please enter a second digit", 0xA,0xD 
    len2 equ $- msg2 

    msg3 db "The sum is: "
    len3 equ $- msg3

    msg4 db "The minus is: "
    len4 equ $- msg4

global _start 

 _start: 

    mov eax, SYS_WRITE   ; System write      
    mov ebx, STDOUT      ; System output   
    mov ecx, msg         ; What to write
    mov edx, len     ; Length to write
    int 0x80             ; Interupt Kernel      

    mov eax, SYS_READ    ; System read
    mov ebx, STDIN       ;
    mov ecx, number1 
    mov edx, 2
    int 0x80            

    mov eax, SYS_WRITE        
    mov ebx, STDOUT         
    mov ecx, msg2          
    mov edx, len2         
    int 0x80

    mov eax, SYS_READ  
    mov ebx, STDIN  
    mov ecx, number2 
    mov edx, 2
    int 0x80        


    call add



add:
    mov eax, SYS_WRITE         
    mov ebx, STDOUT         
    mov ecx, msg3          
    mov edx, len3         
    int 0x80

    ;load number1 into eax and subtract '0' to convert from ASCII to decimal
    mov eax, [number1]
    sub eax, '0'
    ; do the same for number2
    mov ebx, [number2]
    sub ebx, '0'

    ; add eax and ebx, storing the result in eax
    add eax, ebx
    ; add '0' to eax to convert the digit from decimal to ASCII
    add eax, '0'

    ; store the result in result
    mov [result], eax

    ; print the result digit
    mov eax, SYS_WRITE        
    mov ebx, STDOUT
    mov ecx, result         
    mov edx, 1        
    int 0x80 

    ret

minus:

    mov eax, SYS_WRITE         
    mov ebx, STDOUT         
    mov ecx, msg4          
    mov edx, len4         
    int 0x80

    ;load number1 into eax and subtract '0' to convert from ASCII to decimal
    mov eax, [number1]
    sub eax, '0'
    ; do the same for number2
    mov ebx, [number2]
    sub ebx, '0'

    ; add eax and ebx, storing the result in eax
    sub eax, ebx
    ; add '0' to eax to convert the digit from decimal to ASCII
    add eax, '0'

    ; store the result in result
    mov [result2], eax

    ; print the result digit
    mov eax, SYS_WRITE        
    mov ebx, STDOUT
    mov ecx, result         
    mov edx, 1        
    int 0x80

    ret

mul:

   ;load number1 into eax and subtract '0' to convert from ASCII to decimal
    mov al, [number1]
    sub al, '0'
    ; do the same for number2
    mov bl, [number2]
    sub bl, '0'

    ; add eax and ebx, storing the result in eax
    mul bl
    ; add '0' to eax to convert the digit from decimal to ASCII
    add al, '0'

    ; store the result in result
    mov [result], al

    ; print the result digit
    mov eax, SYS_WRITE        
    mov ebx, STDOUT
    mov ecx, result         
    mov edx, 1        
    int 0x80

    ret


exit:    
    mov eax, SYS_EXIT   
    xor ebx, ebx 
    int 0x80

The above code is what i have done so far, I tried to add the numbers but add function seems to be called twice as shown in the picture below. What am i trying to do is to add, subtract, multiply and divide the two numbers. How can i do that and when i try to add 2 numbers sometimes it gave me this output Segmentation fault.enter image description here

KZY
  • 71
  • 1
  • 11
  • In `mov [result], eax` you are accessing the `result` variable as DWORD and not as BYTE like defined in `result resb 1`. This is probably not the root cause, but nevertheless an overflow. – zx485 Jan 17 '18 at 03:35
  • How can fix this ? I just started learning the assembly. – KZY Jan 17 '18 at 04:33
  • how - keep learning, there's certain amount of basic knowledge any decent course/tutorial should teach you, helping with all those basics every time somebody asks on SO is very wasteful, so make sure you exhausted the common obvious sources of knowledge and you have some particular puzzling piece, before asking at SO and point out research you did and what is puzzling you, those Q do lot more better here. See https://stackoverflow.com/tags/x86/info for some resources. In this particular case storing only one byte of `eax` (`mov [result],al`), or allocating 4B by `result: resd 1` or `resb 4`. – Ped7g Jan 17 '18 at 09:10
  • And it looks like you are using NASM assembler, but I would still recommend you to go through this super short [MASM guide](http://www.cs.virginia.edu/~evans/cs216/guides/x86.html) as it contains only few bits of NASM incompatible syntax, and most of the information there is either generic or NASM compatible, it also tackles data sizes and lot more, so it should give you good overview of what you have to search details for. Finding some working debugger solution for yourself is another absolutely essential step. If you will master the `gdb`, good for you, I gave up and compiled edb from github – Ped7g Jan 17 '18 at 09:18
  • Why does your question require an image of your output? Just copy the text into your question. – Jongware Jan 17 '18 at 09:43

1 Answers1

0

You defined your functions in the middle of the _start block.

Single-step your code in a debugger and notice that after call add returns, execution continues into the instructions starting at the add label.

Eventually you crash when you reach the ret, i.e. when you try to ret from _start (because the top of the stack is argc, not an address, at process startup in the System V ABI). Or maybe you even fault earlier; you didn't post debugger output and I didn't simulate it in my head to see what happens.

This is why The sum is: ? is printed twice.

I guess your code also fails to handle multi-digit numbers, so you got the ASCII code '0' + 8+9 or whatever. See How do I print an integer in Assembly Level Programming without printf from the c library?, or a simplified 2-digit-max version of that. Or just use printf if you dynamically link libc, so it can call its own init functions.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • If this is the right answer, it's a duplicate of [NASM assembler - How to make sure the function label isn't executed one extra time?](https://stackoverflow.com/questions/48307937/nasm-assembler-how-to-make-sure-the-function-label-isnt-executed-one-extra-ti) – Peter Cordes Jan 17 '18 at 19:56