title: RISC-V assembly - stack layout - function call
body: <p>Currently I am working with a RISC-V processor implementation. I need to run partially hand-crafted assembly code. (Finally there will be dynamic code injection.) For this purpose I have to understand the basics of function calls within RISC-V assembly.</p>
  <p>I found this topic very helpful: <a href="https://stackoverflow.com/questions/7493785/confusion-about-function-call-stack">confusion about function call stack</a></p>
  <p>But I am still struggling with the stack layout for a function call. Please consider the following c-code:</p>
  <pre><code>void some_func(int a, int b, int* c){
     int cnt = a;
     for(;cnt &gt; 0;cnt--){
        *c += b;
     }
  }
  
  void main(){
     int a = 5;
     int b = 6;
     int c = 0;
  
     some_func(a,b,&amp;c);
  }
  </code></pre>
  <p>This program implements a basic multiplication by a sequence of additions. The derived assembly code (<code>riscv64-unknown-elf-gcc -nostartfiles mul.c -o mul &amp;&amp; riscv64-unknown-elf-objdump -D mul</code>) looks like this:</p>
  <pre><code>0000000000010000 &lt;some_func&gt;:
     10000:   fd010113            addi    sp,sp,-48
     10004:   02813423            sd  s0,40(sp)
     10008:   03010413            addi    s0,sp,48
     1000c:   fca42e23            sw  a0,-36(s0)
     10010:   fcb42c23            sw  a1,-40(s0)
     10014:   fcc43823            sd  a2,-48(s0)
     10018:   fdc42783            lw  a5,-36(s0)
     1001c:   fef42623            sw  a5,-20(s0)
     10020:   0280006f            j   10048 &lt;some_func+0x48&gt;
     10024:   fd043783            ld  a5,-48(s0)
     10028:   0007a703            lw  a4,0(a5)
     1002c:   fd842783            lw  a5,-40(s0)
     10030:   00f7073b            addw    a4,a4,a5
     10034:   fd043783            ld  a5,-48(s0)
     10038:   00e7a023            sw  a4,0(a5)
     1003c:   fec42783            lw  a5,-20(s0)
     10040:   fff7879b            addiw   a5,a5,-1
     10044:   fef42623            sw  a5,-20(s0)
     10048:   fec42783            lw  a5,-20(s0)
     1004c:   fcf04ce3            bgtz    a5,10024 &lt;some_func+0x24&gt;
     10050:   00000013            nop
     10054:   02813403            ld  s0,40(sp)
     10058:   03010113            addi    sp,sp,48
     1005c:   00008067            ret
  
  0000000000010060 &lt;main&gt;:
     10060:   fe010113            addi    sp,sp,-32
     10064:   00113c23            sd  ra,24(sp)
     10068:   00813823            sd  s0,16(sp)
     1006c:   02010413            addi    s0,sp,32
     10070:   00500793            li  a5,5
     10074:   fef42623            sw  a5,-20(s0)
     10078:   00600793            li  a5,6
     1007c:   fef42423            sw  a5,-24(s0)
     10080:   fe042223            sw  zero,-28(s0)
     10084:   fe440793            addi    a5,s0,-28
     10088:   00078613            mv  a2,a5
     1008c:   fe842583            lw  a1,-24(s0)
     10090:   fec42503            lw  a0,-20(s0)
     10094:   f6dff0ef            jal 10000 &lt;some_func&gt;
     10098:   00000013            nop
     1009c:   01813083            ld  ra,24(sp)
     100a0:   01013403            ld  s0,16(sp)
     100a4:   02010113            addi    sp,sp,32
     100a8:   00008067            ret
  </code></pre>
  <p>The important steps that need clarification are: (<code>some_func(int,int,int)</code>)</p>
  <pre><code>   10060:   fe010113            addi    sp,sp,-32
     10064:   00113c23            sd  ra,24(sp)
     10068:   00813823            sd  s0,16(sp)
     1006c:   02010413            addi    s0,sp,32
  </code></pre>
  <p>and: (<code>main()</code>)</p>
  <pre><code>   10000:   fd010113            addi    sp,sp,-48
     10004:   02813423            sd  s0,40(sp)
     10008:   03010413            addi    s0,sp,48
  </code></pre>
  <p>From my understanding: The stack pointer is moved to make space for return-address and parameters. (<code>main</code> might be a special case here.) How are the passed arguments treated when located on the stack? How are they obtained back? In general, the methodology is clear to me, but how would I hand-code this segment in order to work.</p>
  <p>Regarding the related topic, the stack should look somewhat like</p>
  <pre><code>| ???                            |
  | params for some_func() &lt;???&gt;   |
  | ra of some_func()              |
  | locals of main()       &lt;int c&gt; |
  | locals of main()       &lt;int b&gt; |
  | locals of main()       &lt;int a&gt; |
  | params for main()      &lt;None&gt;  |
  </code></pre>
  <p>But that is pretty much it. Can anybody point out, how this is arranged, and how these two listings (function call) co-related?</p>