Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How we can do it in Assembly..Help Needed

Status
Not open for further replies.

Ayne

New Member
Code:
Dim Seg_Display as byte[5]
It creats 5 variables in RAM like this
Seg_Display0
Seg_Display1
Seg_Display2
Seg_Display3
Seg_Display4
we can access any variable.
How we do this in Assembly??

Code:
Dim  Final_Volt    as longint
In this Final_Volt is equal to 32–bit long variable, We can assign any value between -2147483648 ~ 2147483647.
How we definae in assembly that variable(For example Variable Volt) is a longint??

Code:
Dim Seg_Display as byte[5]
Dim        v        as byte

Main:
PORTB  = Seg_Display[v]
Inc(v)
 if v > 4 then
    v = 0 
  end if
Seg_Display[0] = 10011011
Seg_Display[1] = 11001011
Seg_Display[2] = 10111111
Seg_Display[3] = 10111001
Seg_Display[4] = 11111011
Delay_ms(250) 
Goto Main
End

How can we do this in Assembly?
Above all codes written in mikroBasic

I am beginer and learing from Nigel Goodwin's tutorials
Thanks in advance.
 
Code:
Dim Seg_Display as byte[5]
Dim        v        as byte

Main:
PORTB  = Seg_Display[v]
Inc(v)
 if v > 4 then
    v = 0 
  end if
Seg_Display[0] = 10011011
Seg_Display[1] = 11001011
Seg_Display[2] = 10111111
Seg_Display[3] = 10111001
Seg_Display[4] = 11111011
Delay_ms(250) 
Goto Main
End
Plz convert this code in assembly
 
As I'm bored,

Definitely untested,

Code:
		cblock 0x20
Seg_Display:5
v
		endc

Main	incf	v,F
	movfw	v
	sublw	5
	btfsc	STATUS,z
	clrf	v
	movfw	v
	addlw	Seg_Display
	movwf	FSR
             bcf        STATUS,IRP
	movfw	INDF
	movwf	PORTB
	movlw	b'10011011'
	movwf	Seg_Display
	movlw	b'11001011'
	movwf	Seg_Display+1
	movlw	b'10111111'
	movwf	Seg_Display+2
	movlw	b'10111001'
	movwf	Seg_Display+3
	movlw	b'11111011'
	movwf	Seg_Display+4
	goto	Main
 
You can't declare a longint in assembly. The PIC is an 8-bit microcontroller, it can't natively handle anything but 8 bits at a time. If you want a 32-bit value, it's going to be represented as four 8-bit bytes, and you need to do all the math and housekeeping for each of those bytes yourself.
I suggest you check out the following pages, which have a lot of math routines, particularly for handling 16, 24, and 32-bit values in assembly. I think you're going to be disappointed when you realize how complicated it can be.



This is a perfect example of what I (and others) always say: to code effectively on a PIC in a high-level language, you really need to understand how your routines are getting translated to assembly. It's too easy to just throw in 32-bit variables in C or BASIC just because that's the way you do it on a PC, without realizing that the implementation in assembly to perform math operations on them can be a huge, inefficient nightmare.
 
Thank u, now i understand that,
we use "Seg_Display+0" instead "Seg_Display[0]"....(the difference is brakets and in assembly we will use +.

Now second question
Supose i have a variable named "Volt" i want to store a value "146621" . As we can see this value is larger than a byte. Now plz guide me how we store this value in variable??
 
Ayne said:
Thank u, now i understand that,
we use "Seg_Display+0" instead "Seg_Display[0]"....(the difference is brakets and in assembly we will use +.
but you should actually understand what's going on there, rather than just considering it a difference of syntax. 'Seg_Display' represents a memory address. 'Seg_Display+1' represents the next memory address, and so on.

Ayne said:
Supose i have a variable named "Volt" i want to store a value "146621" . As we can see this value is larger than a byte. Now plz guide me how we store this value in variable??
You have to break it up.
146621 = 0b100011110010111101
that particular value is 18 bits in binary. So, presumably you'd store it as a 24-bit value consisting of 3 8-bit values. Look at the binary representation of it - the least significant 8 bits (10111101) would get stored in one byte, the next 8 (00111100) in another byte, and the rest in another byte (00000010). Any time you want to actually USE the variable, you need to use the kind of math routines I linked in my previous post, because unlike 8-bit variables, you can't just use the assembly add and subtract instructions and be done.
 
Last edited:
Is there any easier way for doing this instead adding indivisual byte as in ur example
 
Is there any easier way for doing this instead adding indivisual byte as in ur example
Not without using a 24 or 32bit microcontroller. A PIC24F will make it a little earier because it can do 16bit.
 
Last edited:
You really need to stop and think about whether you actually NEED 24 or 32-bit values in your program. Often, you can reorganize things so it's not necessary - for instance if it's only used for a long timing loop, a couple of nested 8-bit loops is just as good as a single 16-bit loop, and generally makes more sense in assembly.

If you are truly determined to do everything the easy way and not care at all about writing intelligent, efficient code, then you probably won't want to use assembly language, because it doesn't let you get away with it. BASIC and C compilers let you toss around 16, 24, and 32-bit values like you want, however if you do it that way, don't be surprised when your resulting programs compile to extremely large code size, have unexpected problems, and be extremely slow to run - it's not unreasonable to see multiplication and division on 32-bit numbers to take 1000 clock cycles to complete - do that very often and you can absolutely cripple your program on the PIC.
 
Code:
IF (INTCON,TOIF == 1)	;Flag Set if TMR0 Interrupt
 GOTO	INT_TMRO
 ENDIF
Can assembler perform bolean in IF instruction?

Code:
IF(SEGMENT > 32)
		SEGMENT == 2
		ENDIF
I want to check that segment is higher than 32(Decimal) or not.
How to tell the assembler that the value is in Decimal?
I think like below, plz tell me i am wrong or right
Code:
IF(SEGMENT > D'32')
		SEGMENT == 2
		ENDIF
 
Ayne said:
Code:
IF (INTCON,TOIF == 1)	;Flag Set if TMR0 Interrupt
 GOTO	INT_TMRO
 ENDIF
Can assembler perform bolean in IF instruction?

Code:
IF(SEGMENT > 32)
		SEGMENT == 2
		ENDIF
I want to check that segment is higher than 32(Decimal) or not.
How to tell the assembler that the value is in Decimal?
I think like below, plz tell me i am wrong or right
Code:
IF(SEGMENT > D'32')
		SEGMENT == 2
		ENDIF
Code:
        btfsc  INTCON,T0IF
        goto   INT_TMR0


        movfw	SEGMENT;	move segment to working register
        sublw 	.32;		subtract decimal (.) 32
        movlw	.2;		put 2 into work register
        btfss	STATUS,C;	test is w was more than 32
        movwf	SEGMENT;	if it was store W in segment

You can also use d'32' to tell the assembler it is decimal.

MOVPF doesn't exist.

HTH

Mike.
 
I think we can use direct IF command in MPLAB.. What u say?
I am saying Yes because In the MPLAB assembler help file there are examples that using IF command in assembly.

MOVPF doesn't exist.
AN617(Fixed Point Routines) is a file from Microchip. They are useing MOVPF instruction.
 
Ayne said:
I think we can use direct IF command in MPLAB.. What u say?
I am saying Yes because In the MPLAB assembler help file there are examples that using IF command in assembly.

Try reading the helpfile properly - the IF is an assembler directive, it doesn't generate any code.

AN617(Fixed Point Routines) is a file from Microchip. They are useing MOVPF instruction.

It's probably a macro?.
 
;**********************************************************************************************
;
; 16x16 Bit Unsigned Fixed Point Multiply 16 x 16 -> 32
;
; Input: 16 bit unsigned fixed point multiplicand in AARGB0, AARGB1
; 16 bit unsigned fixed point multiplier in BARGB0, BARGB1
;
; Use: CALL FXM1616U
;
; Output: 32 bit unsigned fixed point product in AARGB0, AARGB1,
; AARGB2, AARGB3
;
; Result: AARG <-- AARG * BARG
;
; Max Timing: 26 clks
;
; Min Timing: 26 clks
;
; PM: 25 DM: 7
;
;
FXM1616U MOVPF AARGB1,TEMPB1
MOVFP AARGB1,WREG
MULWF BARGB1
MOVPF PRODH,AARGB2
MOVPF PRODL,AARGB3
MOVFP AARGB0,WREG
MULWF BARGB0
MOVPF PRODH,AARGB0
MOVPF PRODL,AARGB1
MULWF BARGB1
MOVPF PRODL,WREG
ADDWF AARGB2,F
MOVPF PRODH,WREG
ADDWFC AARGB1,F
CLRF WREG,F
ADDWFC AARGB0,F
MOVFP TEMPB1,WREG
MULWF BARGB0
MOVPF PRODL,WREG
ADDWF AARGB2,F
MOVPF PRODH,WREG
ADDWFC AARGB1,F
CLRF WREG,F
ADDWFC AARGB0,F
RETLW 0x00
;*************************************************

This is the code
 
GOTO $ + 4 ; It will jump backward(4 Steps) from it's current location
GOTO $ - 4 ; It will jump forward (4 Steps) from it's current location
In above code i am right or not???

Second
PIC16F877A
i want to multiply, 16x16 Bit Unsigned Fixed Point Multiply 16 x 16 -> 32. Is there any library or any subrutine for this??? Or any thing that can help instead of writing enough large code???
 
Ayne said:
In above code i am right or not???

No you're not right, + jumps forward, and - jumps back.

Second
PIC16F877A
i want to multiply, 16x16 Bit Unsigned Fixed Point Multiply 16 x 16 -> 32. Is there any library or any subrutine for this??? Or any thing that can help instead of writing enough large code???

Check on the PICLIST, there are plenty of maths routines - however, do you REALLY need to use 16 x 16? - often a little thought can greatly simplify what you need to do.

You might also check EPE, they have 32 bit maths routines.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top