assemblyx86nasm

Program doesn't print anything to the console


I have tried writing a simple program that converts 2 digit Roman numbers into 1 digit Arabic number. I don't know where the error could be. I double checked everything multiple times.

According to GNU debugger, the values of AL and BL are as intended. I think that the sys_write fails most of the time. Also, please don't complain about repetitive instructions, I just hate making subroutines.

SECTION .data
zprava db 'rimske cislo:' 
znakyzprava equ $-zprava 
linefeed db 0xA

SECTION .bss
inputcislo resb 2 

SECTION .text
global _start

_start:

mov edx,znakyzprava
mov ecx,zprava
mov ebx,1
mov eax,4
int 80h  

mov edx,2 
mov ecx,inputcislo 
mov ebx,0 
mov eax,3 
int 80h

uzmamdata:

mov al,[inputcislo] 
mov bl,[inputcislo+1]

hodnotyznaku:
cmp al,73
jz ali
cmp al,86
jz alv
cmp al,88
jz alx
pulka:
cmp bl,73
jz ahi
cmp bl,86
jz ahv
cmp bl,88
jz ahx
jmp konechodnot

ali:
mov al,1
jmp pulka
alv:
mov al,5
jmp pulka
alx:
mov al,10
jmp pulka
ahi:
mov bl,1
jmp konechodnot
ahv:
mov bl,5
jmp konechodnot
ahx:
mov bl,10
jmp konechodnot

konechodnot:

cmp al,bl

jg alvet ;kdyz je al vetsi nez ah
jl almen

alvet:
sub al,bl
jmp dale

almen:
add al,bl
jmp dale

dale:

add al,48 

mov edx,1 
mov ecx,0
add cl,al
mov ebx,1
mov eax,4
int 80h

mov edx,1 
mov ecx,linefeed
mov ebx,1
mov eax,4
int 80h

konec:
mov ebx,0
mov eax,1
int 80h

Solution

  • The problem is much the same as it was in your previous question! My answer already explained that you should use a memory buffer, so you can pass its address to sys_write. Make it a sufficiently large general purpose buffer, and set it up in the .bss section:

    SECTION .bss
    buffer resb 4096
    

    Your program should never be relying on any pre-existing contents in that buffer. And to actually demonstrate that it is indeed "general purpose", you can use the same buffer for your input too, meaning you can omit that inputcislo resb 2 reservation.

    mov edx, znakyzprava
    mov ecx, zprava
    mov ebx, 1
    mov eax, 4
    int 80h
    
    mov edx, 2
    mov ecx, buffer
    mov ebx, 0
    mov eax, 3
    int 80h
    
    mov al, [buffer]
    mov bl, [buffer+1]
    
    ...
    
    add al, 48              ; Convert single digit into character
    mov [buffer], al        ; Store to memory
    mov byte [buffer+1], 10 ; Put a newline behind it
    
    mov edx, 2              ; Write both together, you don't need the separate 'linefeed' anymore
    mov ecx, buffer
    mov ebx, 1
    mov eax, 4
    int 80h
    
    konec:
    mov ebx, 0
    mov eax, 1
    int 80h
    

      cmp al,bl
      jg alvet ;kdyz je al vetsi nez ah
      jl almen
    alvet:
      sub al,bl
      jmp dale
    almen:
      add al,bl
      jmp dale
    

    Unrelated, but I think you have the 'addition' and 'subtraction' operations reversed!
    Take the roman number "VI" where you should be adding (5 + 1), or the roman number "IX" where you should be reversed subtracting (10 - 1).
    And you forgot to deal with equal digits; For the roman number "II" you need to add (1 + 1), so not the subtraction that would happen now.

      cmp  al, bl
      jge  almen
    alvet:
      xchg al, bl       ; Put the greater digit in AL first
      sub  al, bl
      jmp  dale
    almen:
      add  al, bl
      jmp  dale