<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Writing all-assembly functions -- syntax, parameter passing, return value in CodeWarrior for MCU</title>
    <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218055#M8644</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I want to write an assembly version of this function:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;uint16_t intel16_asm( uint16_t value);&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Looking at the assembly generated for a C version of that function, it would appear that return address is passed in H:X, the parameter is on the stack (SP+1 holds MSB, SP+2 holds LSB) and the return is expected in H:X.&amp;nbsp; So, I came up with the following assembly to swap the byte order:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;PSHX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; push return addressPSHH LDHX 4, SP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; load LSB of parameter to H, junk to XLDX 3, SP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; load MSB of parameter to XRTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; return&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So what syntax should I use to create this function?&amp;nbsp; Can I mark it as inline and have the compiler inline the assembly so it loads a 16-bit value into H:X and then does the PSHH PSHX PULH PULX sequence to swap the byte order?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried doing:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;uint16_t intel16_asm( uint16_t value){ asm {&amp;nbsp; PSHH&amp;nbsp; PSHX&amp;nbsp; PULH&amp;nbsp; PULX&amp;nbsp; RTS }}&lt;/PRE&gt;&lt;P&gt;But then I get a warning because the function doesn't return.&amp;nbsp; Is it even safe to use RTS in the assembly?&amp;nbsp; If I take the RTS out, how do I indicate to the compiler that the return value is already loaded in H:X?&amp;nbsp; How do I tell the compiler not to push the return address for me?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;If I want to write the 32-bit version of this function, I assume a 32-bit parameter is passed on the stack in a similar fashion?&amp;nbsp; How is a 32-bit return value passed out?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Finally, any recommended tutorials or references for learning HC08 assembly?&amp;nbsp; I did HC11 over 18 years ago, and don't remember anything about it.&amp;nbsp; I've been doing a lot of Rabbit assembly (originally based on Z80 instruction set) over the past 10 years, and so far the HC08 syntax has been very foreign to me.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;-Tom&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;(HC08 with CodeWarrior 5.9.0)&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Fri, 13 Aug 2010 09:20:43 GMT</pubDate>
    <dc:creator>tomlogic</dc:creator>
    <dc:date>2010-08-13T09:20:43Z</dc:date>
    <item>
      <title>Writing all-assembly functions -- syntax, parameter passing, return value</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218055#M8644</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I want to write an assembly version of this function:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;uint16_t intel16_asm( uint16_t value);&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Looking at the assembly generated for a C version of that function, it would appear that return address is passed in H:X, the parameter is on the stack (SP+1 holds MSB, SP+2 holds LSB) and the return is expected in H:X.&amp;nbsp; So, I came up with the following assembly to swap the byte order:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;PSHX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; push return addressPSHH LDHX 4, SP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; load LSB of parameter to H, junk to XLDX 3, SP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; load MSB of parameter to XRTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; return&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So what syntax should I use to create this function?&amp;nbsp; Can I mark it as inline and have the compiler inline the assembly so it loads a 16-bit value into H:X and then does the PSHH PSHX PULH PULX sequence to swap the byte order?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried doing:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;uint16_t intel16_asm( uint16_t value){ asm {&amp;nbsp; PSHH&amp;nbsp; PSHX&amp;nbsp; PULH&amp;nbsp; PULX&amp;nbsp; RTS }}&lt;/PRE&gt;&lt;P&gt;But then I get a warning because the function doesn't return.&amp;nbsp; Is it even safe to use RTS in the assembly?&amp;nbsp; If I take the RTS out, how do I indicate to the compiler that the return value is already loaded in H:X?&amp;nbsp; How do I tell the compiler not to push the return address for me?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;If I want to write the 32-bit version of this function, I assume a 32-bit parameter is passed on the stack in a similar fashion?&amp;nbsp; How is a 32-bit return value passed out?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Finally, any recommended tutorials or references for learning HC08 assembly?&amp;nbsp; I did HC11 over 18 years ago, and don't remember anything about it.&amp;nbsp; I've been doing a lot of Rabbit assembly (originally based on Z80 instruction set) over the past 10 years, and so far the HC08 syntax has been very foreign to me.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;-Tom&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;(HC08 with CodeWarrior 5.9.0)&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 13 Aug 2010 09:20:43 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218055#M8644</guid>
      <dc:creator>tomlogic</dc:creator>
      <dc:date>2010-08-13T09:20:43Z</dc:date>
    </item>
    <item>
      <title>Re: Writing all-assembly functions -- syntax, parameter passing, return value</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218056#M8645</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Well, I finally figured out a workable solution, but it's really ugly.&amp;nbsp; Surely there's an easier way, maybe with just having some assembly outside of the C function?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;#pragma MESSAGE DISABLE C1404  // Return expected#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAME#pragma NO_RETURNuint16_t intel16_asm( uint16_t value){ asm {  PSHH  PSHX  PULH  PULX  RTS }}#pragma MESSAGE DEFAULT C1404&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My first assumption had been right (parameter 1 in H:X), but I second guessed myself and edited the message with the incorrect assumption that H:X had the return address (which wouldn't really make sense).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My confusion came from looking at the disassembly of another function without parameters.&amp;nbsp; It pushed H:X onto the stack right away, but maybe that was to make room for a return value...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 13 Aug 2010 09:57:33 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218056#M8645</guid>
      <dc:creator>tomlogic</dc:creator>
      <dc:date>2010-08-13T09:57:33Z</dc:date>
    </item>
    <item>
      <title>Re: Writing all-assembly functions -- syntax, parameter passing, return value</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218057#M8646</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Has been a while since I last did S08 asm programming, so just some hints.&lt;/P&gt;&lt;P&gt;Note that the calling convention is different for the S08 and for the orginal HC08. As the S08 support more addressing modes with LDHX/STHX, one 16 bit argument is passed in H/X. for the HC08 A and X is used.&lt;/P&gt;&lt;P&gt;Long returns (anything else &amp;gt; 2 bytes) are done with an additional in pointer argument to a buffer.&lt;/P&gt;&lt;P&gt;Check the compiler manual, should have the basic calling convention described in there.&lt;/P&gt;&lt;P&gt;I think using the pragmas is the best way, well the RTS could be done by the compiler, does not really matter.&lt;/P&gt;&lt;P&gt;An alternative would be a plain assembly implementation of the function.&lt;/P&gt;&lt;P&gt;Assembly code outside of function is not allowed, the compiler is not using the assembler but directly emits object files.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Daniel&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 13 Aug 2010 10:36:59 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218057#M8646</guid>
      <dc:creator>CompilerGuru</dc:creator>
      <dc:date>2010-08-13T10:36:59Z</dc:date>
    </item>
    <item>
      <title>Re: Writing all-assembly functions -- syntax, parameter passing, return value</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218058#M8647</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks for the info.&amp;nbsp; I am using an S08, not an HC08.&amp;nbsp; Here's what I came up with for a 32-bit swap:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAME#pragma NO_RETURNuint32_t swap32( uint32_t value){ /* Stack offset:  1: LSB of return address  2: MSB of return address  3: byte0 (LSB) param1  4: byte1 of param1  5: byte2 of param1  6: byte3 of param1  7: LSB of address of return value  8: MSB of address of return value */ asm {  LDHX 7, SP   ; H:X is index to return value  LDA 3, SP   ; load byte 0 of parameter  STA 3, X   ; save as byte 3 of return  LDA 4, SP   ; load byte 1 of parameter  STA 2, X   ; save as byte 2 of return  LDA 5, SP   ; load byte 2 of parameter  STA 1, X   ; save as byte 1 of return  LDA 6, SP   ; load byte 3 of parameter  STA 0, X   ; save as byte 0 of return  RTS }}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 13 Aug 2010 10:40:22 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218058#M8647</guid>
      <dc:creator>tomlogic</dc:creator>
      <dc:date>2010-08-13T10:40:22Z</dc:date>
    </item>
    <item>
      <title>Re: Writing all-assembly functions -- syntax, parameter passing, return value</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218059#M8648</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Looks reasonable.&lt;/P&gt;&lt;P&gt;In the comment, the MSB and LSB's are in the wrong order, S08's are big endian, therefore the MSB is at the lower address.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 13 Aug 2010 10:49:23 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218059#M8648</guid>
      <dc:creator>CompilerGuru</dc:creator>
      <dc:date>2010-08-13T10:49:23Z</dc:date>
    </item>
    <item>
      <title>Re: Writing all-assembly functions -- syntax, parameter passing, return value</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218060#M8649</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For the 16-bit case, the following appears to generate efficient code.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;uint16_t intel16( uint16_t value){  (void)value;  // Avoids unused parameter compiler warning    __asm {    pulh    pulx    pshh    pshx  }  return value;}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Since the entry to the function already pushes the argument onto the stack from H:X, the idea is to pull off the stack, and replace to the stack in reverse order.&amp;nbsp;&amp;nbsp;An interesting observation is that the compiler actually optimises away the function entry pushes, and the subsequent inline pulls,&amp;nbsp;leaving the following resultant code for the function,&amp;nbsp;that achieves the required result.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;   pshh   pshx   ldhx  1,sp   ais   #2   rts&lt;/PRE&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Mac&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 13 Aug 2010 12:11:51 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/Writing-all-assembly-functions-syntax-parameter-passing-return/m-p/218060#M8649</guid>
      <dc:creator>bigmac</dc:creator>
      <dc:date>2010-08-13T12:11:51Z</dc:date>
    </item>
  </channel>
</rss>

