movlw - literally bonkers - Page 1
Forum section: electronics / general

author: PerranOak
author_rank: Frequent Contributor
timestamp: July 09, 2018, 04:41:24 pm
content: I took the instructionmovlw"move literal to W" to be literally that.However, in the EEPROM section it gives a piece of example code thus:MOVLW DATA_EE_ADDRwhich is a variable not a literal. Have I gone mad?

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: July 09, 2018, 04:47:24 pm
content: Quote from: PerranOak on July 09, 2018, 04:41:24 pmDATA_EE_ADDR is a probably a constant, i.e. the address in eeprom where something will get stored

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 09, 2018, 05:10:09 pm
content: Quote from: mikeselectricstuff on July 09, 2018, 04:47:24 pmI'm pretty sure it is. Would help to see the DATA_EE_ADDR declaration part of the code though.

author: cv007
author_rank: Frequent Contributor
timestamp: July 09, 2018, 05:37:46 pm
content: To read a data memory location, the user must write theaddress to the EEADRL register...BANKSEL EEADRL ;MOVLW DATA_EE_ADDR ;MOVWF EEADRL ;Data Memory;Address to readBCF EECON1, CFGS ;Deselect Config spaceBCF EECON1, EEPGD;Point to DATA memoryBSF EECON1, RD ;EE ReadMOVF EEDATL, W ;W = EEDATLIn the datasheet example, instead of using a literal number for the movlw, they are assuming you can figure out that they are suggesting DATA_EE_ADDR is the address you want to read.

author: PerranOak
author_rank: Frequent Contributor
timestamp: July 09, 2018, 08:29:40 pm
content: … so they are saying that DATA_EE_ADDR is used to represent a number … like … 7? Why would anyone code a constant in that position?Am I just being really thick?

author: Kleinstein
author_rank: Super Contributor
timestamp: July 09, 2018, 08:51:47 pm
content: DATA_EE_ADDR most likely represents a constant number, that is defined somewhere in a device specific include file (HW definitions). It is common practice to use such constructs to define the specific HW this way. Ideally there should be no constants directly in the code - maybe except for small integers like 1 , 2 , ... 4.

author: cv007
author_rank: Frequent Contributor
timestamp: July 09, 2018, 09:07:03 pm
content: QuoteJust a little.The example is to show you how to read data from a single eeprom address. From there, you can come up with your own way to get your wanted address into EEADRL. You are not going to literally copy/paste that example into working code. If it makes it easier, just replace DATA_EE_ADDR with <THE_NUMBER_YOU_WANT_GOES_HERE_BUT_WE_ARE_NOT_TELLING_YOU_HOW_TO_GET_THE_NUMBER_FROM_WHEREVER_TO_HERE>

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: July 09, 2018, 09:27:51 pm
content: ..and why are you dicking around in assembler - use C

author: mikerj
author_rank: Super Contributor
timestamp: July 09, 2018, 09:50:24 pm
content: Quote from: PerranOak on July 09, 2018, 08:29:40 pmNot thick, but I'm guessing you haven't done much programming? If you were looking at this code, which version would give you the biggest hint on what it's doing; the magic number '7' or the defined symbol 'DATA_EE_ADDR'?Now imagine that this register is referenced from many different parts of the code, and you want to move the code to a new part. Unfortunately the EE DATA register was moved to a different address. If you've used the number '7' all over your code, you now have to find and replace every instance. If you used DATA_EE_ADDR it's almost certainly defined in a device specific header, so all you need to do is include the appropriate header or the new device (and this is usually done automatically when you select the new device in the build manager).

author: T3sl4co1l
author_rank: Super Contributor
timestamp: July 10, 2018, 12:31:24 am
content: What's up with the ALLCAPS? Even in assembler, I make sure to distinguish CONSTANT_VALUES and EQU_LITERALS from memoryLocations or FunctionPointers (give or take what prefixes and CamelCase you want to employ for various labels in your project).If these distinctions aren't clear or apparent, don't be afraid to open up the include files where they are defined. Preferably, find an IDE that gives you a rich view of your files/project (mouse hover or CTRL+SPACE or whatever to see namespace references, etc.). I'm not sure offhand if Code::Blocks does this for asm? It's nice for C, at least. Or maybe you're stuck with whatever IDE you're using, no idea.What's up with ALLCAPS in general? So much asm I see is allcaps, and it's so grating to read. Do you hate yourself? (Well, you're writing in ASM, I guess that's a given.) (That's a collective "you", including the last ~decades of asm history.)Tim (hates self enough to have written many things in asm).

author: cv007
author_rank: Frequent Contributor
timestamp: July 10, 2018, 04:03:20 am
content: To make it clear to all, although not stated very well in the original post, he is referring to a datasheet example (pic16something) where they show some code to read from the eeprom. There is no DATA_EE_ADDR. There is no include. There is no define. There is no .set, etc.Its simple datasheet example code (which I posted earlier, so others can see what he is talking about).

author: westfw
author_rank: Super Contributor
timestamp: July 10, 2018, 07:32:08 am
content: In between an instruction set for a CPU, and the assembler defined for that CPU, there are usually instructions for loading the data contents at a memory location, AND instructions for loading the address of the memory location (essentially, to a pointer.)Code:MOVLW DATA_EE_ADDRis essentiall similar to the C statement:Code:W = &DATA_EE_ADDR;Some combinations will use different opcodes, some just different formats for the operands.Here's a try at some examples. (Some of them are probably a bit far off; it's been a while since I've done much assembly language programming.)Code:.data.org 200. ;; start this block of data at 200 for some reason.MYDATA: .word 123. ;; define some data. It'll be sorta like this..textPDP10: move 1, MYDATA. ;; puts 123 into register 1 (the value stored in MYDATA)movei 1, MYDATA ;; puts 200 into register 1 (the address of MYDATA)MASM86: mov MYDATA, ax. ;; move 123 into register axmov $MYDATA, ax ;; 200 in ax.PIC: MOVF MYDATA, W ;; move 123 into Wmovlw MYDATA. ;; move 200 into W.AVR: lds r16, MYDATA ;; 123 into r16ldi r16, MYDATA ;; 200 in r16ARM: ldr r3, MYDATA ;; loads 123 (maybe PC relative with limitations.)adr r3, MYDATA ;; loads 200 (similar limitations.)

author: PerranOak
author_rank: Frequent Contributor
timestamp: July 10, 2018, 02:56:07 pm
content: Many thanks to everyone.I think it was that I was always expecting to see a number with movlw and never anything else. I see that the DATA_EE_ADDR "item" is just representative of a number (like "n" or "your num" which would have been less confusing) not a variable. The thing is that I often use underscores in variable names and so it looked like a variable to me.Yes, I am dicking around in assembly but that's because I'm new to microcontrollers and my first lessons were in assembly. My attention has been diverted into this project of my own to see if I can use what I've learned. Also, I noticed that all the examples in datasheets seem to be in assembly and I couldn't understand them. My next set of lessons, after this project, are in C.One thing I wondered is once C programmes are compiled are they generally as efficient in space and speed as "assembled assembly"?

author: NorthGuy
author_rank: Super Contributor
timestamp: July 10, 2018, 03:14:23 pm
content: Quote from: PerranOak on July 10, 2018, 02:56:07 pmAssembler is typically 2-3 times more efficient than C, however the efficiency depends mostly on how you program. An ill-minded programmer may write code which is 100 times less efficient than it could've been. This dwarfs the difference between C and assembler.Besides, most of the time, you don't need high efficiency, so you don't even need to worry about efficiency at all. Simply don't write something really stupid (such as very long floating point calculations inside an interrupt), and you'll be Ok.

author: ejeffrey
author_rank: Super Contributor
timestamp: July 10, 2018, 04:12:05 pm
content: Quote from: PerranOak on July 10, 2018, 02:56:07 pmIt is pretty common in all languages -- including assembly -- to use "named constants". The syntax and semantics vary with language, but in compiled and assembled languages they are treated as compile time constants that cannot be modified and get converted to their actual constant number at compile time. The reason for this is that it makes it easier to read and promotes code reuse. For instance, DATA_EE_ADDR might be different on different processor within the same family.QuoteBasically that depends on what you are doing and what platform you are using. On a very simple platform like PIC, average human assembly will probably be a bit more efficient than average human C code. In superscalar CPUs with multiple levels of cache and branch prediction (like an intel or ARM application processor), typical human code will usually be worse than typical C compiler code. This is especially true of x86 where complex addressing modes and special purpose instructions are supported for backwards compatibility but multiple simpler instructions (aka, more "RISC like") may be faster on the modern incarnations. It typically takes a human a lot of work and a lot of trial and error to get better than the compiler.One partial exception is SIMD. Automatic vectorization by compilers is still not very good. Even for languages with native vector types, compilers have trouble mapping that onto the fixed options of their native SIMD registers. You can use "vector intrinsics" which just look like functions that call specific assembler opcodes. This basically lets you somewhat freely intermingle C code with native assembly and still let the compiler try to optimize things like loop unrolling and prefetching. This is still very much "try a bunch of variants and see which is actually fastest" and AFAIK, people who do serious optimization still usually use inline assembly instead, but I think a novice is likely to get better performance with the vector intrinsics than inline assembly on the first try.

author: TomS_
author_rank: Frequent Contributor
timestamp: July 13, 2018, 08:49:34 am
content: Quote from: PerranOak on July 09, 2018, 04:41:24 pmDATA_EE_ADDR may be a variable, in which case it has a value associated with it. The assembler will replace the name of the symbol with its value when generating output.Perhaps the use of "literal" is a little less .. literal .. in this case, as there are other move instructions which can move registers between each other. So this is simply a distinction that movlw moves "literal" values, which could also be the contents of a variable, rather than the contents of another register?

author: jpanhalt
author_rank: Super Contributor
timestamp: July 13, 2018, 10:22:44 am
content: Quote from: PerranOak on July 09, 2018, 08:29:40 pmAs others have said, it is the location/address. That is fixed in silicon and is not a variable. What you call it doesn't matter.Maybe this will help you see the difference. In an earlier thread you mentioned using "equ" . That is also an address in the context of your use at the time. Say you write: DATA_EE_ADDR equ 0x20 Then you write, movlw DATA_EE_ADDR. WREG will have 0x20 in it. If you write movf DATA_EE_ADDR,W , then WREG will have the contents of the register at 0x20 in it.EEPROM is no different. It just uses a different section of memory and different registers to access.

author: jpanhalt
author_rank: Super Contributor
timestamp: July 13, 2018, 10:32:10 am
content: @PerranOakSince you seem to be just starting out ...The PIC16F18xx chips are a great set of chips. If you have you 16F1827 up and running in real life, not just sim, ignore the rest of this comment.If not, consider a 12F509 or any 12F5xx for a starter. They are limited chips and lack such peripherals as comparators, have a slightly more limited instruction set, and no interrupts. Because of those limitations, they are easy to get running (say to flash an LED) in silicon.Once you get the feel for them though, moving to anything in the mid-range or enhanced mid-range is extremely easy. Even the 18F's are not that that different.

author: Mechatrommer
author_rank: Super Contributor
timestamp: July 13, 2018, 12:27:23 pm
content: Quote from: mikeselectricstuff on July 09, 2018, 04:47:24 pmQuote from: Kleinstein on July 09, 2018, 08:51:47 pmnot probably nor most likely. it is exactly a constant number, otherwise the compiler (or assembler whatever that is) will throw an error..Quote from: PerranOak on July 10, 2018, 02:56:07 pmthere is no such thing as variables (and names) in assembly, everythings are numbers. number to literally a number, or number representing an address to something be it register, flash, memory or anything else in your mind it is... think about pointers in C, its just a number representing an address to a memory location.

author: jpanhalt
author_rank: Super Contributor
timestamp: July 13, 2018, 12:45:35 pm
content: Quote from: Mechatrommer on July 13, 2018, 12:27:23 pmI think that last statement is a little strong. There can be just as many "variables" in assembly as in any other MCU language, e.g., C or PICBasic.Otherwise, how do you measure an analog signal, do a calculation, and print the result to a display?

author: Mechatrommer
author_rank: Super Contributor
timestamp: July 13, 2018, 01:03:03 pm
content: i'm taking from assembler point of view. variable is just a concept in human mind how they interpret things, just as how pointer in C. when we really get down to it, its just 0 and 1, but i will not get into that and you may discuss at which level you wish... ymmv..

author: a59d1
author_rank: Regular Contributor
timestamp: July 20, 2018, 05:20:59 am
content: Quote from: T3sl4co1l on July 10, 2018, 12:31:24 amGotta make yourself feel like you're writing COBOL all the time.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: July 21, 2018, 08:31:28 pm
content: Quote from: jpanhalt on July 13, 2018, 10:32:10 am16F153xx are better - dual SPI/UARTS, and remappable pin functions ( for at least one of each peripheral type)

author: jpanhalt
author_rank: Super Contributor
timestamp: July 21, 2018, 08:58:21 pm
content: Quote from: mikeselectricstuff on July 21, 2018, 08:31:28 pmYep, those those 5-digit chips are at the other end of the spectrum for 8-bit devices. Problem is that for Assembly programming, MPLab 8.92 doesn't support them. So, you are forced to use the newer IDE's, which can seem unfriendly by comparison.