-3

I'm learning assembly right now and I have a very big problem to solve. (I use x86_64 nasm assembly btw)

So far, I have done this

section .bss
    result: resb 10
section .data
    num1: db '22'
    num2: db '33'
    num3: db '44'

section .text
    global _start
_start:
    mov cl, [num1]
    cmp cl, [num2]
    jg _check_third_num
    mov cl, [num2]

_check_third_num:
    cmp cl, [num3]
    jg _exit
    mov cl, [num3]
_exit: 
    mov [result], rcx
    mov rax, 1
    mov rdi, 1
    mov rsi, result
    mov rdx, 10

    syscall
    mov rax, 60
    mov rdi, 0

    syscall

I guess it's worked as I expected, but the output isn't right.

So, I basically compiled like this

     $ nasm -f elf64 hello.asm -o hello.o
     $ ld -o hello hello.o
     $ ./hello

And I get this output 4, not 44 as I wish to.

So can you help me?

  • Is the comparison logic flawed, or just the output ? –  Dec 02 '22 at 12:40
  • 2
    Your numbers are strings so your comparison is already wrong as it only compares the first digit and that is the digit you will print at the end since that's the only thing you loaded into `cl`. – Jester Dec 02 '22 at 12:42
  • Even I change it to number it cant even run as I expected to – KhanhDong Dec 02 '22 at 12:45
  • You need to *compare* as binary numbers read into variables/registers but *output* as decimal-digit strings. – ecm Dec 02 '22 at 12:46
  • So better discard all the irrelevant part of the code and adapt the title. –  Dec 02 '22 at 12:49
  • @KhanhDong That will work to convert a single-digit number in register `cl` to a single decimal digit codepoint. You will have to actually divide/modulo by 10 repeatedly if you want to handle numbers larger than 9, though. – ecm Dec 02 '22 at 12:49

1 Answers1

0

So, I was on the Indian tutorial (which personally so bad). They said that we can compare strings as a replacement of numbers. But, for sure, that doesn't work properly.

Also, I will get that work for <10 numbers. For >10 numbers, I think I'll get it soon.

section .bss
    result: resb 2
section .data
    num1: db 9
    num2: db 8
    num3: db 7

section .text
    global _start
_start:
    mov cl, [num1]
    cmp cl, [num2]
    jg _check_third_num
    mov cl, [num2]

_check_third_num:
    cmp cl, [num3]
    jg _exit
    mov cl, [num3]
_exit: 
    add rcx, '0'
    mov [result], rcx
    mov rax, 1
    mov rdi, 1
    mov rsi, result
    mov rdx, 2

    syscall
    mov rax, 60
    mov rdi, 0

    syscall
E_net4
  • 27,810
  • 13
  • 101
  • 139
  • 1
    You can compare fixed-length 4-byte strings as dword integers, but you have to `bswap` first so the leading byte (most significant in printing order) swaps to the most-significant position in the integer value. This isn't fully correct either; you store 8 bytes to `result` but you only reserved space for 2. And you pass `length = 2` in RDX, but the 2nd byte is a binary 0 (assuming you statically link this and run on a normal Linux kernel, otherwise it's garbage because you only merged a new CL into RCX, not `movzx ecx, byte [num1]`.) – Peter Cordes Dec 02 '22 at 13:27
  • 1
    As for int->string conversion for numbers > 10, see [How do I print an integer in Assembly Level Programming without printf from the c library?](https://stackoverflow.com/a/46301894) – Peter Cordes Dec 02 '22 at 13:32