Hello everyone,
I know this forum is more about asm86 but I thought maybe someone knows enough about assembly in general or had some expirience in asm51 as well and can help me with my questions(wich are simple),
I needed a 16bit(word) counter and I didn't have appropriate register for that in 89S52,so I wrote the following code in asm51 for the 89S52 microcontroller:
ORG 50h
counter DW #0FA0h
...
DEC counter
...
JZ counter,label3
...

(the "..." comes instead of large pieces of code,"label3" is a label later in the code) my questions are:
Is my code correct,
can I use a defined memory cell the way I used it?
Am I decriecing the word correctly or I need special instructions for that?


Thank you,
Arctic wolf.

I needed a 16bit(word) counter and I didn't have appropriate register for that in 89S52,so I wrote the following code in asm51 for the 89S52 microcontroller:

ORG 50h
counter DW #0FA0h
...
DEC counter
...
JZ counter,label3
...

(the "..." comes instead of large pieces of code,"label3" is a label later in the code) my questions are:

Is my code correct, can I use a defined memory cell the way I used
it?

Nope. In my experience, a DW declaration defines a 16-bit location in program memory, using it to store a specific value. You'll have to copy that value down into internal RAM before you can work on it. Internal RAM holds random values at power-up.

The MCS51 family is Harvard-architecture, where program and data storage are separate: unless you are using dual-addressed RAM (read in with both RD* and PSEN* strobes), you can't execute out of RAM. Nor can you read or write locations in external RAM except with MOVX instructions.

In practice, that copy-down is better done using two "mov location,#value" statements, where the two immediate-values are the high and low bytes of an already-declared symbol. In MCS51, unlike other Intel asemblers for 8080, 8085, 8086 etc., the convention is hi-byte-first, going by how the program counter is stored to the stack in a call, so those two mov instructions will put the hi-byte in "location" and the lo-byte in "location+1". Splitting the symbol-value into hi and lo bytes might take macros; that varies by assembler.

Am I decriecing the word correctly or I need special instructions for
that?

Nope, sorry. There is no 16-bit decrement (and the only 16-bit increment is INC DPTR). Your decrement will only affect the first byte of the word, and it won't affect any flags, the zero-flag in particular, so the JZ that follows won't do what you want.

Here's code you might want to use. I'm capitalizing all symbolic addresses here. I'm coding off the top of my head (and it's been awhile), so do step this code before you trust it.

dec	LOBYTE    ; the low byte of the down-counter
  mov   a,LOBYTE
  cjne  a,#0FFh,CHECK_FOR_ZERO
  dec   HIBYTE     ; we hit rollunder, so tick down the hibyte
CHECK_FOR_ZERO:   
  orl   a,HIBYTE    ; test both bytes. zero?
  jnz   NOT_YET
  { code to execute at 16-bit-zero }
NOT_YET:
  { assuming your code carries on after responding to the zero }

crb3 Hello and thank you.
And yeah,I already found out the same information you told me about.
I solved the problem by using 2 registers instead of one.
Unfortunatley it will take more time to execute(the program is real time),but I don't think that it will cause a big problem...
Appreciate the code example,thank you. I used a little different code but the principle is the same..

A.

This article has been dead for over six months. Start a new discussion instead.