• VaxMan (unregistered)

    Of course proper architectures have a way of expressing this as one opcode (EXTVW IIRC).

    Bliss even had a way to code it up angle brackets maybe?

  • Cornify (unregistered)

    I'm always using the wrong EMV_ADK_BYTE with the wrong EMV_ADK_NIBBLE and getting the wrong data back without any error.

  • Cornify (unregistered)

    Seems I was unaware the * is markup for italic text

  • Your Name (unregistered)

    *Nybble. Otherwise the bite/byte pun is meaningless

  • carsten (unregistered)

    This is what you get when people learn to code in abstract languages and then need to work with low level byte operations. How could they know of C struct and union features.

  • maurizio (unregistered)

    What's wrong with struct and bitfields ?

  • Brian (unregistered)

    Yep, using struct & union is a standard pattern for this kind of operation. Just need something like this (been a while since I've done low-level dev; my memory may be a bit fuzzy):

    struct EMV_ADK { union { uint64 all; struct { uint64 manual_reversal : 4; uint64 refund : 4; uint64 reservation : 4; uint64 tip : 4; // etc... } } }

  • Brian (unregistered) in reply to Brian

    Guess I need to figure out how formatting works here.

  • Appalled (unregistered) in reply to Brian
    Formatting doesn't work unless you either:
    
    1.  hit enter twice for a new line
    2.  Surround your code with 
    
    
    1. Surround your code with

    Of course this is just a test. We'll see if they've mucked it all up AGAIN.

  • RLB (unregistered)

    The only reason I can think of for this structure of surprises is if EDV_AFK_REFUSE_NO and siblings - i.e., the actual values being compared against - do, for some reason, have to have specific values. If those aren't used anywhere else in the remaining code except for comparing to these shifticles, I'm stumped as well. (Even if they are, there are better ways, of course.)

  • Appalled (unregistered)
    I forgot, the final display removes the tags, pretend the XRE's in the following are PRE
    
    <XRE>
    Formatting doesn't work unless you either:
    
    1.  Hit enter twice for a new line
    2.  Surround your code with 
    3.  Surround your code with 
    </XRE>
  • Bob (unregistered) in reply to Brian

    You are assuming that the order of the data in memory doesn't matter. That might not be the case, it could be the information has come in a binary form from another entity.

  • ajb (unregistered)

    Bitfields in C are not strictly portable--allocation of elements is defined by the ABI, and not all toolchains expose options to override the defined behavior to whatever it is you want. So if the bitfields are only ever used within one application, or only ever with ABIs that are known to provide the same ordering/spanning/packing behavior, then there's no trouble. Otherwise, use them with caution.

    For best portability, bitmasks/shifts or other operations where the developer explicitly defines the element ordering are generally preferred.

  • Taffer (unregistered)

    At least it's documented?

  • (nodebb) in reply to Taffer

    Actually, I think it's an ethos.

  • LCrawford (unregistered)

    This is for embedded systems where the more logical ntohs() and htons() combined with a union would take too long to execute.

  • nb (unregistered) in reply to Brian

    Struct and union technically is not guaranteed to operate correctly by the C standard, so... bitmasks are the "proper" pattern. That said, if you have control of the build process and you know that your environment correctly supports the struct/union then that is a hell of a lot more readable.

  • Herby (unregistered)

    ..."Struct and union technically is not guaranteed to operate correctly by the C standard, so... " I would agree, but the code in the original posting isn't very portable either. One should realize that portability doesn't really matter if the implementation is consistent from one module to another. Someone must have put the data in the 64 bit entity (somewhere), and if you use the same structure in both places, it can be implemented differently, but still be "portable".

    Yes, it is a mess!

  • Sole Purpose of VIsit (unregistered) in reply to Appalled

    You work with the facilities provided.

    What is your problem, little man? Software, as with life, is not designed specifically with you in mind.

  • Ross (unregistered) in reply to Appalled

    Formatting doesn't work.

    There, fixed that for you.

  • Appalled (unregistered) in reply to Sole Purpose of VIsit

    WTF is YOUR problem BIG MAN. There ARE NO FACILITIES PROVIDED. The forum does not and probably never will have an "Add Code Sample" button or instructions on how to do so by hand. So I answered his question about how to freaking do it, PRE tags. If I had known you were gonna flame me I woulda just said "View Source". Take a hike nutjob.

  • siciac (unregistered)

    Software, as with life, is not designed specifically with you in mind.

    Spare us the moralfagging.

  • ZB (unregistered)

    "Imagine, if you will, that you have 64-bits of data."

    I'd rather imagine I'm in a world where people don't obsessively stick hyphens after numbers where they don't belong.

  • Dellapa (unregistered) in reply to Appalled

    I think Ross is, in a very funny way, referring to point 2 and 3 of your enumeration.

    Maybe you want to elaborate what your problem is?

  • Anonymous (unregistered)

    You know, apart from the obvious WTF of defining a macro (>> 4 & 0x0F) without parentheses this code actually isn't so bad.

    To me the bigger WTF here is everyone (developer/submitter, Remy, readers) assuming that this code is not optimal for the platform it was written for.

    1. You don't know where the 64-bit value came from or where it was going. I am pretty sure it was already in memory as part of some request or response message, not written out solely so it can be checked.
    2. What guarantee you have that (most likely ARM9) architecture executing this code can load, shift and mask 64-bit values?
    3. What guarantee you have that 32-bit (or 64-bit if they exist) loads, shifts, and masks are faster or translate to shorter code than the 8-bit ones used?
    4. Bitfields are not portable, EMV standard changes all the time, endianness of the data can be different than that of the platform.
    5. What if it was done this way to work around a bug in an ancient gcc compiler port for the embedded platform which once cost $3,500 and is no longer updated?

    In other words, without knowing the code history you can't judge it.

  • Worf (unregistered)

    For point #2, it's easy. If the compiler can handle 64-bit types internally, it can emit code to handle 64-bit types even on architectures that have no native 64-bit support. 64-bit integers weren't introduced with 64-bit computers - compiler support has been around a long time and I've had 64-bit types long before I even had access to ARMs using 64-bit.

    Hint: There are compiler support libraries that do this work for you. Missing them can lead to oddball missing defines like __eabi_uldiv32 or other symbols, because the compiler was dealing with something the ARM doesn't natively handle.

    As long as you have compiler support, use it. This method works, but it leads to all sorts of oddball bugs if you do mess up the array index and masking parameters. And given how the names are similar, it's very easy to miss and overlook.

  • (nodebb)
    Formatting code is
    just a case of inserting
    four extra spaces.
    
  • Anonymous (unregistered) in reply to Worf

    And what if the platform compiler does not provide such library support?

Leave a comment on “Take a Byte of a Nibble”

Log In or post as a guest

Replying to comment #:

« Return to Article