Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMP function always returns jg after comparison in NASM

I have the following code which I run online on this website:

section .bss
    num resq 1
section .text
    global _start       
_start:                     
    mov eax, 4      
    mov ebx, 1      
    mov ecx, msg
    mov edx, len    
    int 0x80        
      
    mov eax, 3       
    mov ebx, 0       
    mov ecx, num
    mov edx, 8   
    int 0x80
    
    mov eax,[num]
    cmp eax,0
    jl negative_label
    je equal_label
    jg positive_label
    
equal_label:
    mov eax,4
    mov ebx,1
    mov ecx,equal_text
    mov edx,3
    int 0x80
    jmp exit
positive_label:
    mov eax,4
    mov ebx,1
    mov ecx,pos_text
    mov edx,3
    int 0x80
    jmp exit
negative_label:
    mov eax,4
    mov ebx,1
    mov ecx,neg_text
    mov edx,3
    int 0x80
    jmp exit
exit:
    mov eax,1
    mov ebx,0
    int 0x80
section .data

msg db  'Hello, world!',0xa,0
len equ $ - msg
pos_text db "Poz"
neg_text db "Neg"
equal_text db "Nul"

I want to check if a number that the user inputted was positive, negative, or zero. Basically I want to make a program that let's the user enter numbers until they enter zero (0) and it prints out sum of all the numbers typed before.
So, if the user's input is: "1,-3,3,4", the expected output would be "5" since that is the sum of the above numbers.

I tried doing sub instruction to turn the num value into number but either I am doing it wrong or it's not the way to do it.

Please feel free to criticize my code, I am a beginner and a solution would be great.

like image 559
hail1401 Avatar asked Dec 21 '25 20:12

hail1401


1 Answers

If the user inputs the text "1,-3,3,4", then the memory at num will hold the following 8 bytes: 0x31, 0x2C, 0x2D, 0x33, 0x2C, 0x33, 0x2C, 0x34.
Your instruction mov eax,[num] will be retrieving the first 4 bytes so that the EAX register will contain 0x332D2C31. This value in EAX does not reflect any of the individual single-digit numbers that are of intrest to you, and so comparing this EAX to zero makes no sense in the context of classifying the (single-digit) numbers.
What needs to be done is looping over the string while validating, classifying, converting, summing, ...

This is my suggestion

section .bss
    res   resd 1
    num   resb 8
section .text
    global _start
_start:              

    ...

    mov   ebx, num            ; Address of the text
    xor   ecx, ecx            ; Sum
.a: movzx eax, byte [ebx]     ; Current character
    sub   eax, '0'            ; Convert to digit [0,9] IF it is ["0","9"]
    jz    .d                  ; Null '0' provides an early out
    cmp   eax, 9              ; Comma ',' and Minus '-' get skipped here
    ja    .c                  ;  together will everything else
    cmp   byte [ebx - 1], '-' ; Has [1,9] a minus prepended?
    jne   .b                  ; Go add positive
    neg   eax                 ; From [1,9] to [-1,-9], go add negative
.b: add   ecx, eax
.c: inc   ebx                 ; Move to next character
    cmp   ebx, num + 8        ; Continu the loop while not at the end
    jb    .a
.d: mov   [res], ecx

You can use next simplified print-out only if the final sum in ECX should happen to be a single-digit number:

mov   eax, 4      
mov   ebx, 1      
mov   ecx, res
add   byte [res], '0'
mov   edx, 1    
int   0x80 

The above code snippet shows that it is not particularly hard to program this task. I really cannot agree with one of the other answers that uses words as:

If You are a beginner, you should begin with an easier program
... it's not easy to do with assembly
... and it's also hard
... it's also very difficult

like image 105
Sep Roland Avatar answered Dec 24 '25 10:12

Sep Roland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!