asm question

Discussion in 'Programmer's Corner' started by tracecom, Jan 27, 2014.

  1. tracecom

    Thread Starter AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    I know nothing about C, so please forgive the stupid questions.

    Does this line of code agree with the explanation of what it does?

    Code ( (Unknown Language)):
    1. ;     if(datahi == 0x0F)        // if data == 0xF0..0xFF
    What does the == mean?

    Thanks.
     
    Last edited: Jan 27, 2014
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,386
    496
    That is not assembler. That is C.
     
  3. tracecom

    Thread Starter AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    So, that makes it clear that I don't know anything about assembler or C.

    I still would like the answers to my questions.

    Thanks.
     
  4. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,386
    496
    The == means equal.

    When you see =, not ==, that means something is assigned to something. Like A=5 means 5 is assigned to or stored in variable A.

    When you see ==, double equal, that means I am comparing one "thing" to another "thing". The "things" could be numbers or something else.

    Since this is if statement. We basically have: if hex value stored in variable called datahi is same as 0x0F, then do whatever is inside the if statement.
     
  5. tracecom

    Thread Starter AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    It looks to my uneducated mind as if the explanation is defining a range of values, i.e., from hex F0 to hex FF. Is that correct, and if not, how should the explanation be understood?

    Thanks.
     
  6. MrChips

    Moderator

    Oct 2, 2009
    12,429
    3,360
    In C the following statement:

    A = 123;

    means assign A with the value 123. The equal sign is called the assignment operator.


    Where as the expression

    (A == 123)

    returns a boolean value, TRUE or FALSE.

    == is a comparison or relational operator, i.e. it compares the left hand expression with the right hand expression and returns a boolean result.
     
  7. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,386
    496
    Also, the explanation is wrong.

    The way that if statement is done, it only works for one case. When datahi is 0x0F. The if statement does not include situations when datahi is 0x1F or 0x2F or 0x3F, etc. But the note says that it should work for all the values of datahi, from 0x0F to 0xFF.
     
  8. MrChips

    Moderator

    Oct 2, 2009
    12,429
    3,360
    Code ( (Unknown Language)):
    1.  
    2. if(datahi == 0x0F)        // if data == 0xF0..0xFF
    3.  
    The comment is incorrect or taken out of context.
     
  9. tracecom

    Thread Starter AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    There's the answer to my first question. I didn't think the if statement agreed with the explanation. How would one correct the if statement to make it agree with the explanation?

    Thanks.
     
  10. WBahn

    Moderator

    Mar 31, 2012
    17,718
    4,788
    What kind of variable is datahi?

    It is implied (and only implied -- I'm having to read between the lines here) that there is a one byte variable (probably unsigned char) called datahi and that there is also a similar variable called datalo and that, combined, these form a two byte variable called data.

    The code provided checks to see if the variable datahi is 0x0F. Since datalo is not being checked at all, it can be anything. Thus, this test will pass if data is anything between 0x0F00 and 0x0FFF.

    That doesn't quite agree with the comment, so that might only mean that I'm reading between the wrong lines.
     
  11. WBahn

    Moderator

    Mar 31, 2012
    17,718
    4,788
    You want to force the bits that you don't care about to be either a 0 or a 1 and then check accordingly.

    For instance:

    if ((datahi&0x0F) == 0x0F)

    The & is the bitwise AND operator and will force the upper nibble to be zero while keeping the lower nibble intact.

    There are other ways to do it, too.
     
  12. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,386
    496
    To make the if statement fit the explanations, you could do it this simple way:
    if(datahi==0x0F || datahi==0x10 || datahi==0x11 || etc.)
    {
    "do whatever needs to be done"
    }
    || is logical OR

    Another way to do it is to use a bunch of if statements:
    if(datahi==0x0F)
    {
    "do whatever needs to be done"
    }
    if(datahi==0x10)
    {
    "do whatever needs to be done"
    }
    if(datahi==0x11)
    {
    "do whatever needs to be done"
    }
    and so on until you execute datahi==0xFF

    You can do it with if/else statements. You can do it with Case statements.
     
  13. MrChips

    Moderator

    Oct 2, 2009
    12,429
    3,360
    Here is code to suit the comment statement:

    Code ( (Unknown Language)):
    1.  
    2.    if( (datahi & 0xF0) == 0xF0 )    // if data == 0xF0..0xFF
    3.     {
    4.     }
    5.  
    6.  
     
  14. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    990
    It really depend on what that comment means.

    It could also mean:

    if(datahi >= 0x0F || datahi <= 0xff)

    Or datahi is greater or equal to 0x0f or datahi is less than or equal to 0xff.
     
  15. tracecom

    Thread Starter AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    Here is the first half of the code as written and posted by Mike McLaren. Apparently it's too long to include in one post, so I will put the last half in another post.) I had hoped he would happen by, but so far has not. So, I am trying to troubleshoot code that I don't understand. The whole story is in this thread.


    Code ( (Unknown Language)):
    1. ;******************************************************************
    2. ;                                                                 *
    3. ;   Filename: ezLCD v3 (12F683).asm                               *
    4. ;     Author: Mike McLaren, K8LH                                  *
    5. ;    (C)2010: Micro Application Consultants, All Rights Reserved  *
    6. ;       Date: 08-Dec-11  (rev:111210.0637z)                       *
    7. ;                                                                 *
    8. ;   K8LH 12F683 serial HD44780 LCD 4-bit interface experiment     *
    9. ;                                                                 *
    10. ;   8-bit test code.  this interface traps a 0xFE character and   *
    11. ;   writes the character immediately following it to the LCD as   *
    12. ;   a command character (RS = 0)                                  *
    13. ;                                                                 *
    14. ;                                                                 *
    15. ;      MPLab: 8.80    (tabs=8)                                    *
    16. ;      MPAsm: 5.43                                                *
    17. ;                                                                 *
    18. ;******************************************************************
    19.  
    20.     #include <p12f683.inc>
    21.     list st=off
    22.     errorlevel -302
    23.  
    24.     radix   dec
    25.  
    26.     __config  _FCMEN_OFF&_IESO_OFF&_MCLRE_OFF&_WDT_OFF&_INTRC_OSC_NOCLKOUT
    27.  
    28. ;--< variables >---------------------------------------------------
    29.  
    30. datahi  equ     0x40            ; shadow for 1st nibble
    31. datalo  equ     0x41            ; shadow for 2nd nibble
    32. temp    equ     0x42            ; low level LCD routines
    33. delayhi equ     0x43            ;
    34. rsflag  equ     0x44            ;
    35.  
    36. ;--< constants >---------------------------------------------------
    37. ;
    38. ;  bit time (cycles) used to sample a serial bit stream
    39. ;
    40. ;   19200 baud, 104 (104.2) cycles, 0.16% bit rate error
    41. ;   57600 baud,  35 ( 34.7) cycles, 0.80% bit rate error
    42. ;  115200 baud,  17 ( 17.4) cycles, 2.08% bit rate error
    43. ;  250000 baud,   8 (  8.0) cycles, 0.00% bit rate error
    44. ;
    45. clock   equ     8               ; 8 MHz clock
    46. usecs   equ     clock/4         ; cycles/usec multiplier
    47. msecs   equ     clock/4*1000    ; cycles/msec multiplier
    48. bRate   equ     9600            ; baudrate 19200, 57600 or 115200
    49. bTime   equ     (usecs*10000000/bRate+5)/10
    50.                                 ; bTime = 104, 35 or 17 cycles
    51. ;
    52. #define D4      0               ; GP0 -> LCD 'D4'
    53. #define D5      1               ; GP1 -> LCD 'D5'
    54. #define D6      2               ; GP2 -> LCD 'D6'
    55. #define SerPin  GPIO,3          ; GP3 -> Serial Input
    56. #define D7      4               ; GP4 -> LCD 'D7'
    57. #define E       5               ; GP5 -> LCD 'E'
    58.  
    59. #define RS      D4              ; RS 'rc' integrator on D4 pin
    60.  
    61. ;--< macros >------------------------------------------------------
    62. ;
    63. ;  inDlyCy() in-line delay macro, range 1..1023 cycles,
    64. ;  produces 1 to 6 instructions.
    65. ;
    66. inDlyCy macro   pTime
    67.         local   dloop
    68.       if pTime > 3
    69.         movlw   (pTime)/4-1     ;
    70. dloop   addlw   -1              ;
    71.         bc      dloop           ;
    72.       endif
    73.       if pTime%4 & 1
    74.         nop                     ; 1 cycle
    75.       endif
    76.       if pTime%4 & 2
    77.         goto    $+1             ; 2 cycles
    78.       endif
    79.         endm
    80. ;
    81. ;  K8LH DelayCy() subsystem macro generates four instructions
    82. ;
    83. DelayCy macro   delay           ; 11..327690 cycle range
    84.         movlw   high((delay-11)/5)+1
    85.         movwf   delayhi
    86.         movlw   low ((delay-11)/5)
    87.         call    uDelay-((delay-11)%5)
    88.         endm
    89.  
    90. ;******************************************************************
    91. ;   Reset Vector                                                  *
    92. ;******************************************************************
    93.  
    94.         org     0x0000
    95. v_reset
    96.         clrf    STATUS          ;                  |B0
    97.         goto    Main            ;                                 |B0
    98.  
    99. ;******************************************************************
    100. ;   Interrupt Vector                                              *
    101. ;******************************************************************
    102.  
    103.         org     0x0004
    104. v_int
    105. ;
    106. ;  using IOC interrupt on start bit leading edge
    107. ;
    108.         inDlyCy(bTime/2-4)      ; half bit time minus 4 cycles    |B0
    109.         movlw   1<<E            ; preset E bit                    |B0
    110.         movwf   datahi          ;                                 |B0
    111.         movwf   datalo          ;                                 |B0
    112. ;
    113. ;  collect lo nibble in 'datalo' (LCD data bits b0..b3)
    114. ;
    115. bit0    inDlyCy(bTime-3)        ;                                 |B0
    116.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    117.         bsf     datalo,D4       ; set LCD D4 shadow bit           |B0
    118. bit1    inDlyCy(bTime-2)        ;                                 |B0
    119.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    120.         bsf     datalo,D5       ; set LCD D5 shadow bit           |B0
    121. bit2    inDlyCy(bTime-2)        ;                                 |B0
    122.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    123.         bsf     datalo,D6       ; set LCD D6 shadow bit           |B0
    124. bit3    inDlyCy(bTime-2)        ;                                 |B0
    125.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    126.         bsf     datalo,D7       ; set LCD D7 shadow bit           |B0
    127. ;
    128. ;  collect hi nibble in 'datahi' (LCD data bits b4..b7)
    129. ;
    130. bit4    inDlyCy(bTime-2)        ;                                 |B0
    131.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    132.         bsf     datahi,D4       ; set LCD D4 shadow bit           |B0
    133. bit5    inDlyCy(bTime-2)        ;                                 |B0
    134.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    135.         bsf     datahi,D5       ; set LCD D5 shadow bit           |B0
    136. bit6    inDlyCy(bTime-2)        ;                                 |B0
    137.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    138.         bsf     datahi,D6       ; set LCD D6 shadow bit           |B0
    139. bit7    inDlyCy(bTime-2)        ;                                 |B0
    140.         btfsc   SerPin          ; bit = 0?  yes, skip, else       |B0
    141.         bsf     datahi,D7       ; set LCD D7 shadow bit           |B0
    142.  
    143.  
     
  16. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,386
    496
    I like it. It much shorter then what I proposed using ||, OR, operator.
     
  17. tracecom

    Thread Starter AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    Do semicolons mean the code is Rem'd out?

    Code ( (Unknown Language)):
    1. ;
    2. ;     if(datahi == 0x0F)        // if data == 0xF0..0xFF
    3. ;     { datahi.E = 0;           // don't write LCD (E bit off)
    4. ;       datalo.E = 0;           // don't write LCD (E bit off)
    5. ;     }                         //
    6. ;     gpio = rsflag;            // charge or drain RS cap
    7. ;     delay_us(3);              //
    8. ;     gpio = datahi;            // setup D4..D7 and E=1
    9. ;     gpio.E = 0;               // E = 0 (write LCD)
    10. ;     gpio = rsflag;            // charge or drain RS cap
    11. ;     delay_us(3);              //
    12. ;     gpio = datalo;            // setup D4..D7 and E=1
    13. ;     gpio.E = 0;               // E = 0 (write LCD)
    14. ;
    15. ;     rsflag ^= 1<<RS;          // toggle rs flag
    16. ;     if(datahi.E)              // if not 0xFE character
    17. ;       rsflag = 1<<RS;         // reset rs flag (RS=1)
    18. ;
    19. wrhi
    20.         movf    rsflag,W        ; the RS bit flag & mask          |B0
    21.         movwf   GPIO            ; charge or drain RS cap          |B0
    22.         movlw   b'00110111'     ; mask for datahi = 0x0F          |B0 --
    23.         xorwf   datahi,W        ; is data == 0xF0..0xFF?          |B0 --
    24.         skpnz                   ; no, skip, else                  |B0 --
    25.         bcf     datahi,E        ; don't write LCD                 |B0 --
    26.         skpnz                   ; no, skip, else                  |B0 --
    27.         bcf     datalo,E        ; don't write LCD                 |B0 --
    28.         movf    datahi,W        ; get data 7..4 bits              |B0
    29.         movwf   GPIO            ; setup D4..D7, E=1               |B0
    30.         bcf     GPIO,E          ; E = 0 (write LCD)               |B0
    31. wrlo
    32.         movf    rsflag,W        ; the RS bit flag & mask          |B0
    33.         movwf   GPIO            ; charge or drain RS cap          |B0
    34.         movlw   1<<RS           ;                                 |B0 --
    35.         xorwf   rsflag,F        ; toggle RS flag & mask           |B0 --
    36.         btfsc   datahi,E        ; if datahi not 0x0F              |B0 --
    37.         iorwf   rsflag,F        ; reset RS flag & mask (RS=1)     |B0 --
    38.         goto    $+1             ;                                 |B0 --
    39.         movf    datalo,W        ; get data 3..0 bits              |B0
    40.         movwf   GPIO            ; setup D4..D7, E = 1             |B0
    41.         bcf     GPIO,E          ; E = 0 (write LCD)               |B0
    42. stop
    43.         inDlyCy(bTime-24)       ; during middle of stop bit       |B0
    44.         movf    GPIO,W          ; clear IOC mismatch              |B0
    45.         bcf     INTCON,GPIF     ; clear IOC interrupt flag        |B0
    46.         retfie                  ;                                 |B0
    47.  
    48. ;******************************************************************
    49. ;  main                                                           *
    50. ;******************************************************************
    51. ;
    52. ;  void main()
    53. ;  {
    54. ;    cmcon0 = 7;                // comparator off
    55. ;    gpio = 0;                  // clear gpio output latches
    56. ;    trisio = 0b00001000;       // gp3 input, others outputs
    57. ;    osccon = 0b01110000;       // setup intosc for 8 MHz
    58. ;    while(osccon.HTS == 0);    // wait for osc stable
    59. ;
    60. Main
    61.         movlw   b'00000111'     ;                                 |B0
    62.         movwf   CMCON0          ; comparator off                  |B0
    63.         clrf    GPIO            ; clear GPIO output latches       |B0
    64.         bsf     STATUS,RP0      ; bank 1                          |B1
    65. ;       clrf    ANSEL           ; no analog, all digital          |B1
    66.         movlw   b'00001000'     ; GP3 input, all others outputs   |B1
    67.         movwf   TRISIO          ;                                 |B1
    68.         movwf   IOCA            ; enable IOC for GP3 'SerPin'     |B1
    69.         movlw   b'01110000'     ;                                 |B1
    70.         movwf   OSCCON          ; 8-mhz INTOSC system clock       |B1
    71. stable  btfss   OSCCON,HTS      ; oscillator stable?              |B1
    72.         goto    stable          ; no, branch, else                |B1
    73. ;
    74. ;  HD44780 "initialize by instruction" for 4-bit interface mode
    75. ;
    76.         bcf     STATUS,RP0      ; bank 0                          |B0
    77.         DelayCy(50*msecs)       ; LCD 50 msec 'power up' reset    |B0
    78.         movlw   0x03            ; hi nibble of "8-bit" command    |B0
    79.         call    PutNyb          ; step 1 (send nibble only)       |B0
    80.         DelayCy(4*msecs)        ; required 4 msec delay           |B0
    81.         movlw   0x03            ;                                 |B0
    82.         call    PutNyb          ; step 2 (send nibble only)       |B0
    83.         DelayCy(160*usecs)      ; (n/a for serial interface)      |B0
    84.         movlw   0x03            ;                                 |B0
    85.         call    PutNyb          ; step 3 (send nibble only)       |B0
    86.         DelayCy(160*usecs)      ; (n/a for serial interface)      |B0
    87.         movlw   0x02            ; hi nibble of "4-bit" command    |B0
    88.         call    PutNyb          ; select 4-bit interface mode     |B0
    89.         DelayCy(160*usecs)      ; (n/a for serial interface)      |B0
    90.         movlw   0x28            ; 4-bit, 2-lines, 5x7 font        |B0
    91.         call    PutCmd          ; send "function set" command     |B0
    92.         movlw   0x0C            ; display on, cursor & blink off  |B0
    93.         call    PutCmd          ; send "display on/off" command   |B0
    94.         movlw   0x06            ; cursor inc, shift off           |B0
    95.         call    PutCmd          ; send "entry mode set" command   |B0
    96.         movlw   0x01            ; clear display (1.53-msecs)      |B0
    97.         call    PutCmd          ; send "entry mode set" command   |B0
    98.         DelayCy(1530*usecs)     ; 1.53 msec delay for "clear"     |B0
    99. ;
    100. ; // setup RA3 'SerPin' for interrupt-on-change
    101. ;
    102. ;    rsflag = 1<<RS;            // set RS flag & mask
    103. ;    while(SerPin == 0);        // wait for hi level on GP3
    104. ;    temp = gpio;               // clear any mismatch condx
    105. ;    intcon.RAIF = 0;           // clear IOC interrupt flag
    106. ;    ioca.IOCA3 = 1;            // eanble IOC for GP3 'SerPin'
    107. ;    intcon.GIE = 1;            // enable global interrupts
    108. ;
    109. ;    while(1);                  // loop forever
    110. ;  }
    111. ;
    112.         bcf     STATUS,RP0      ; bank 0                          |B0
    113.         movlw   1<<RS           ;                                 |B0
    114.         movwf   rsflag          ; set RS flag & mask (RS=1)       |B0
    115.         btfss   SerPin          ; stop state? yes, skip, else     |B0
    116.         goto    $-1             ; loop (wait)                     |B0
    117.         movf    GPIO,W          ; clear GPIO mismatch condition   |B0
    118.         bcf     INTCON,GPIF     ; clear IOC interrupt flag        |B0
    119.         bsf     INTCON,GIE      ; enable global interrupts        |B0
    120.         bsf     INTCON,GPIE     ; enable 'IOC' interrupts         |B0
    121. loop
    122.         goto    loop            ; loop forever                    |B0
    123.  
    124. ;******************************************************************
    125. ;  low level lcd subroutines                                      *
    126. ;******************************************************************
    127.  
    128. PutCmd                          ; entry point for "cmd" data
    129.         clrc                    ; RS = 0 (command)                |B?
    130.         skpnc                   ; skip unconditionally            |B?
    131. PutDat                          ; entry point for "dat" data
    132.         setc                    ; RS = 1 (data)                   |B?
    133.         banksel temp            ; bank 0                          |B0
    134.         movwf   temp            ; save WREG data byte             |B0
    135.         swapf   temp,W          ;                                 |B0
    136.         call    PutNyb          ; send hi nybble                  |B0
    137.         swapf   temp,W          ;                                 |B0
    138.         call    PutNyb          ; send lo nybble                  |B0
    139.         DelayCy(50*usecs)       ; required between writes         |B0
    140.         return                  ;                                 |B0
    141. PutNyb
    142.         movwf   temp            ;                                 |B0
    143.         bcf     GPIO,RS         ; RS = 0 (discharge RS cap)       |B0
    144.         skpnc                   ; RS = 0?  yes, skip, else        |B0
    145.         bsf     GPIO,RS         ; RS = 1 (charge RS cap)          |B0
    146.         movlw   1<<E            ;                                 |B0
    147.         btfsc   temp,0          ;                                 |B0
    148.         iorlw   1<<D4           ;                                 |B0
    149.         btfsc   temp,1          ; b1 = 0?  yes, skip, else        |B0
    150.         iorlw   1<<D5           ;                                 |B0
    151.         btfsc   temp,2          ; b2 = 0?  yes, skip, else        |B0
    152.         iorlw   1<<D6           ;                                 |B0
    153.         btfsc   temp,3          ; b3 = 0?  yes, skip, else        |B0
    154.         iorlw   1<<D7           ;                                 |B0
    155.         movwf   GPIO            ; LCD D4..D7 = data1, E = 1       |B0
    156.         bcf     GPIO,E          ; E = 0                           |B0
    157.         return                  ;                                 |B0
    158.  
    159. ;******************************************************************
    160. ;  K8LH DelayCy() 16-bit uDelay (11..327690 cycle) subroutine     *
    161. ;******************************************************************
    162.         nop                     ; entry for (delay-11)%5 == 4     |B0
    163.         nop                     ; entry for (delay-11)%5 == 3     |B0
    164.         nop                     ; entry for (delay-11)%5 == 2     |B0
    165.         nop                     ; entry for (delay-11)%5 == 1     |B0
    166. uDelay  addlw   -1              ; subtract 5 cycle loop time      |B0
    167.         skpc                    ; borrow? no, skip, else          |B0
    168.         decfsz  delayhi,F       ; done?  yes, skip, else          |B0
    169.         goto    uDelay          ; do another loop                 |B0
    170.         return                  ; return with C = Z = 0           |B0
    171.  
    172. ;******************************************************************
    173.         end
    174.  
    175.  
     
  18. tracecom

    Thread Starter AAC Fanatic!

    Apr 16, 2010
    3,869
    1,393
    I know that I have made a jumbled mess out of my question. It's complicated, I'm tired, and the wife is unhappy about something I said. :(
     
  19. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,386
    496
    Ok. That one is combination of assembler and C. It depends on software environment/infrastructure, some support assembler sections in C, some don't.
     
  20. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,866
    990
    That is assembler. The ; is a comment. The comments are in C. Very odd. It might be a conversion of a C program or the assembler code could be what that C code is supposed to produce. I did not look at the assembler code in detail.
     
Loading...