This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

IF statement in assembly

I'm wondering, Does assembler support if staments? (like a C program) Tried something very simple:

org 0h
sjmp BEGIN

org 50h
BEGIN:
	IF R0 == #45
		MOV A, #54
		CPL A
	ELSE
		MOV A, #45
		CPL A
	ENDIF
END

After building and enter debug mode I found this code seems to be a #ifdef like statement instead of a C like if-then-else statement. Did I do something wrong or the assembler does no support if statement?

  • IF R0 ==
    can not be done ITS CODE, you can not do an not an IF on a register

    cjne AR0,#45,not45
    mov a,#-54
    sjmp done
    not45: mov a,#-45
    done:

  • Does assembler support if staments

    Yes, but not in the way that you mean.

    There are several conditional statements you can use in assembly, but the can only check the values of SET, EQU, or other fixed expressions. They cannot check things that change at runtime.

    Refer to:

    http://www.keil.com/support/man/docs/a51/a51_ap_conditional.htm

    Jon

  • This simple example it's just a #ifdef for set/equ. That's too bad, C-like IF statament would make life much easier. Thank you both for reply.

  • Sergio,

    Yes, you can implement assembly IF statements using ASM macros, but they won't read like higher level if statements.

    Still the same, such macros for ASM51 are very useful and, if you code a lot of assembly, I'd recommend creating a "language extension" file that contains all of your useful a51 macros. Following is an example of just a few test/jump macros. Note, there's nothing magical about these; they simply consolidate some of the more commonly used opcode sequences. There's many other categories of macros that can be considered as well...namely DPTR related code sequences.

    	; IF x < y THEN GOTO addr
    	;
    	jl			MACRO	x, y, addr
    				clr		c
    				mov		a, x
    				subb	a, y
    				jc		addr
    				ENDM
    
    
    	; IF x <= y THEN GOTO addr
    	;
    	jle			MACRO	x, y, addr
    				clr		c
    				mov		a, y
    				subb	a, x
    				jnc		addr
    				ENDM
    
    
    	; IF x > y THEN GOTO addr
    	;
    	jg			MACRO	x, y, addr
    				clr		c
    				mov		a, y
    				subb	a, x
    				jc		addr
    				ENDM
    
    
    	; IF x >= y THEN GOTO addr
    	;
    	jge			MACRO	x, y, addr
    				clr		c
    				mov		a, x
    				subb	a, y
    				jnc		addr
    				ENDM
    
    
    	jne			MACRO	x, y, addr
    				mov		a, x
    				xrl		a, y
    				jnz		addr
    				ENDM
    
    	je			MACRO	x, y, addr
    				mov		a, x
    				xrl		a, y
    				jz		addr
    				ENDM
    

    example use:
        ; If R0 <= B, then jump to MyJumpAddr
        ;
        jle    R0, B, MyJumpAddr
    

  • "Did I do something wrong or the assembler does no support if statement?"

    What you did wrong is to try to guess!

    Do not guess - read the Manual and get the definitive answer!

  • That's too bad, C-like IF statament would make life much easier.

    Indeed. That's why there's a C-like if statement --- in C. If C is what you want, use it. If C and assembly were the same thing, as your wish essentially implies, one of the two would be superfluous.

  • jl		MACRO	x, y, addr
    [...]

    A hint regarding all those macros: cjne is better for most of these than subb or xrl. In particular, you can easily get three exits from a single macro: one for a < b, one for a == b, and one for a > b. And the content of the accu at exit from the macro will be one of its operands, rather than their difference.

  • A hint regarding all those macros: cjne is better for most of these than subb or xrl. In particular, you can easily get three exits from a single macro: one for a < b, one for a == b, and one for a > b. And the content of the accu at exit from the macro will be one of its operands, rather than their difference.

    Obviously, but CJNE doesn't accept just any operands. The macros as they're written, on the other hand, will accept any Rn, #data, or direct in either x or y parameter.

    True, they may not be as efficient as possible, but the couple of extra machine cycles is a small price to pay to have intuitive instructions that work for any type of operands.

  • Thank you Robert, that helped me a lot.

  • I using a AT89C51, it got just 4kbytes on-chip rom memory. One of the goals is to make the circuit smaller then I don't use external ROM. The program need to do lots of stuff (until now I got ~1000 lines of pure code). I think writing in C would make the program too big for 4kbytes of ROM. Of course I would like to write in C, much easier, but sometimes we need to do some sacrifice...Before you say: No I can't change the uController! :(

  • "True, they may not be as efficient as possible, but the couple of extra machine cycles is a small price to pay to have intuitive instructions that work for any type of operands."

    The implication behind the question is that the OP wants to use assembler because he believes it will be more efficient than 'C'.
    Thus, making the assembler inefficient to match the convenience of 'C' entirely defeats the object!

    This also serves to illustrate the fallacy of assuming that something written in assembler will inherently be more efficient than something written in 'C' - you can easily write inefficient assembler if you choose to (or if you don't have the skill to do otherwise).

    As Hans-Bernhard said, if you want the convenience of 'C' - then use 'C'!!

  • "I think writing in C would make the program too big for 4kbytes of ROM."

    Not necessarily.
    Sure, if you write bad, inefficient 'C' it will be bloated - but if you write it carefully, with due consideration for the underlying architecture, and take full advantage of all the optimisation options, there is absolutely no reason at all why you shouldn't use C51 to write useful programs in under 4K.

    Search this forum, and the C51 Manual for tips on writing efficient 'C' for the 8051.

  • "I using a AT89C51 ... One of the goals is to make the circuit smaller then I don't use external ROM ... No I can't change the uController!"

    Why not?

    You say you're making the circuit smaller - that must mean a hardware re-design, so why not take advantage of that and choose a variant with more on-chip ROM?!

    You could fit about three modern QFP derivatives with probably >64K flash each into the space of a 40-pin DIP! - not to mention the external ROM!!

  • It's easy to change de project now, but my teacher will not allow it. I did buy a 32kbytes chip on past week(before start writing the code), but if you are a teacher you must understand that he wants to learn assembly(or he is just being sarcastic hehehe), yesterday I past all day optimizing the code, I did remove a lot of useless staff.