assembly (8086) if statement

Discussion in 'Programmer's Corner' started by fortune2k, Mar 25, 2009.

  1. fortune2k

    Thread Starter Member

    Mar 18, 2009
    Hi im working on a bit of homework and rather stuck

    this is what im trying to do

    Code ( (Unknown Language)):
    2.    0) initialise a temporary numerical value to 00H, base value to 10H and count value to 00H
    3.   1) Read in a character
    4.   2) Apply series of checks  against ‘0’-‘9’ and ‘A’-‘F’ and convert the digit to a numerical value as described above
    5.   3) multiply our temporary numerical value by the base (10H) – remember that mul multiplies the src with what is in AL or AX so we need to make sure that the temporary numerical value is moved into AX before we multiply and since AL contains our digit numerical value we will need to push AX to save it for use later - use version b) of mul i.e. src is 16 bit, result in high word in DX (we will discard this) and low word in AX (which we will use). We can safely multiply by the base the first time round as the temporary numerical value will start out as initilised to 0.
    6.   5) pop AX so we can get the new numerical digit value and add it to the temporary numerical value
    7.   6) increment count of digits converted and go back to 1)
    9.   Note – you will also need to echo the digit characters input, but you should ignore i.e. not echo, the non-hex digit termination character.
    and well this is what i have

    Code ( (Unknown Language)):
    2. BITS 16                 ;Set code generation to 16 bit mode
    3. ORG 0x0100;
    4. SECTION .text;
    6. MAIN:
    7.     ;call upon the subroutines
    8.     call Getch
    9.     call Putln
    10.     call Putch
    11.     call Putln
    12.     call Exit
    14.  %include "Stdio.asm"
    Code ( (Unknown Language)):
    3. ;*************************************************************
    4. ;Subroutine Name:  Putch
    5. ;Function:         Outputs a character at the cursor position
    6. ;                  in the console window by calling DOS INT21H
    7. ;Entry Conditions: Character to be output in DL
    8. ;Exit Conditions:  None
    9. ;Exceptions:       None
    10. ;*************************************************************
    11. Putch:
    12. MOV AH, 02h ; display subprogram
    13. INT 21H
    14. RET ; return
    18. ;*************************************************************
    19. ;Subroutine Name:  Getch
    20. ;Function:         Obtains character input from the keyboard
    21. ;Entry Conditions: Character to be moved into DL
    22. ;Exit Conditions:  None
    23. ;Exceptions:       None
    24. ;*************************************************************
    25. Getch:
    26. MOV ah, 1h ; keyboard input subprogram
    27. int 21h ; read character into al
    28. mov DL, AL
    29. RET ; return
    34. ;*************************************************************
    35. ;Subroutine Name:  Putln
    36. ;Function:         Outputs a new line at the cursor position
    37. ;                  in the console window by calling DOS INT21H
    38. ;Entry Conditions: Character to be output in AH
    39. ;Exit Conditions:  None
    40. ;Exceptions:       None
    41. ;*************************************************************
    42. Putln: ;new line
    43. mov dl, 0DH ;Carriage return
    44. int 21h
    45. mov dl, 0AH  ;Line feed
    46. int 21H
    47. RET ; return
    50. ;*************************************************************
    51. ;Subroutine Name:  Exit
    52. ;Function:         When called upon it will exit the program
    53. ;Entry Conditions: None
    54. ;Exit Conditions:  None
    55. ;Exceptions:       None
    56. ;*************************************************************
    57. Exit:
    58.     mov AX, 04C00H
    59.     int 21H
    im stuck on part 1 / 2 atm (for some reason my program atm allows you to input up to 3 character and they will be echo'd onto the screen no idea why only 3 )

    anyway what im trying to work on is a if statement i want somthing like
    if(AH>=30h | AH <=39)
    ;the value of the character is 0-9

    else(AH>=41h | AH <=51)
    ;the value is A-Z

    how can i do this in nasm assembler?

    i have been messing around with :
    Code ( (Unknown Language)):
    2.     CMP DL ,30h ;if (DL>=0)  
    3.     JGE IF09 ;jump to if09 , if true
    i want like 2 conditions =>0 <=9

    then once i have made sure the value is 0-9 or A-Z then i can do step 3 which i dont really have any idea on how im going to do that either

    thanks in advance
  2. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    cmpl $9, %eax ; <=9
    jle Label
    cmpl $0, %eax ; >= 0
    jg Label

    Move tests to register, worked for me.
  3. fortune2k

    Thread Starter Member

    Mar 18, 2009

    those don't seem to work im getting errors like 'error: parser: instruction expect' and 'error: symbol 'cmpl' redefined'

    im using nasmide to compile and run my nasm assembler in because the school is making us


    Code ( (Unknown Language)):
    2.     call Getch        
    3.     CMP DL ,39h ;if (DL<=9)  
    4.     JLE IF09 ;jump to if09 , if true
    5.     CMP DL ,30h ;if (DL>=0)  
    6.     JGE IF09 ;jump to if09 , if true    
    thats what im trying but it doesnt work no matter wat it always jumps to the IF09 label
    Last edited: Mar 26, 2009
  4. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    the partial snippet above built with nasm on Linux-AMD64, it's all I had handy.

    Although I put the labels wrong, it's an OR above, but the comparison/jump works.

    What are your included files to get the "instruction redefined" error?

    You may want to check an nasm specific forum with this, it looks like it should work, though I haven't done x86 assembly in... forever.
  5. fortune2k

    Thread Starter Member

    Mar 18, 2009
    okky what are the commands u use and stuff soo i can research them and maybe understand them and get them working :)
    i think i need to find out how to do AND . i can do a single true if statement



    IF <=09 and >=0

    IF <=Z and >=a
    ;JUMP to LABEL

    16bit nasm assembler
    Last edited: Mar 26, 2009
  6. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    There isn't a single command to check for greater than AND less than.

    I'll rewrite the two steps I had above for AND
    Code ( (Unknown Language)):
    2. cmp    $9, %eax ; <=9
    3.  jle Test2
    4. jmp Error
    5. Test2:
    6.  cmp    $0, %eax  ; Test for positive number
    7.  jg Continue
    8. jmp Error
    9. Continue:
    10. ...
  7. fortune2k

    Thread Starter Member

    Mar 18, 2009

    agh okky im starting to get it not how ever

    what does this bit do "cmp $9, %eax " whats being compared ? and that does the %eax do?
  8. Mark44

    Well-Known Member

    Nov 26, 2007
    On x86 machines, it should be
    Code ( (Unknown Language)):
    2. cmp eax, 9
    eax is the extended (32-bit) AX register. If your program is 16-bit, as you show in your first post, you'll need to use the AX register, since all the registers are 16 bits.

    cmp ax, 9 compares the contents of the ax register and the literal value 9 by subtracting 9 from what's in the ax register. The subtraction is performed, but the register involved doesn't change. How you tell what the result of the comparison is by inspecting the sign flag (SF) and zero flag (ZF), two flags in the flags register.

    Your code for putch, getch, etc. uses the old DOS int 21H routines, which means that this code has to run on some version of DOS (like MSDOC or PCDOS) or pretty old versions of Windows (Windows 3.1 or earlier). I don't think it will run on Windows 95, and I know for sure it won't run on Windows 98 or any Windows version after that. Linux is another story that I don't know anything about.
  9. fortune2k

    Thread Starter Member

    Mar 18, 2009
    right after a while i think i have managed to do it :
    Code ( (Unknown Language)):
    2.         CMP DL ,39h ;if (DL<=9)  
    3.         JLE IF09 ;jump to IF09 , if true
    5.         CMP DL ,46h ;if (DL<=F)  
    6.         JLE  IFAZ ;jump to IFAF , if true
    11.     IF09:
    12.         CMP DL,30h ;if (DL>=0)
    13.         JGE Continue ;jump to Continue , if true
    15.     IFAZ:
    16.         CMP DL ,41h ;if (DL>=A)
    17.         JGE Continue ;jump to Continue , if true
    19.     Continue:
    20.         inc CX ; adds 1 to CX, CX counts the amount of converted
    22.         MOV AH,09h ;test shit
    23.         LEA DX,[msg]
    24.         Int 21h
    27. msg: db 'VALID$'
    thats works fine 0-9 A-F however it goes to the continue label if i put in characters like / ; ' - = - + . why is this happening surely the if statements should prevent those characters getting to the continue label ? anyone know why this is happening and how to stop this?

    btw im working with nasm 16bit assembly
  10. Mark44

    Well-Known Member

    Nov 26, 2007
    There are no if statements in your assembly code. Your logic uses CMP and jumps (JLE and JGE) to simulate if statements.

    Your code above works as expected if what's in DL is any of the characters '0' through '9', which is your intent. The problem is that there are a bunch of characters with ASCII codes less than 39h, including the one's you're seeing, and a bunch of others that don't display.

    What you need is two checks: one that the character is greater than or equal to '0' and another the the character is less than or equal to '9'. Same thing for the characters 'A' through 'F', and you might want to check the lower case characters 'a' through 'f'.
  11. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6 tests, actually
    >= 0 ($0 = zero)
    <= 9 ($9 = nine)
    >= ASCII A
    <= ASCII F
    >= ASCII a
    <= ASCII f