Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.asm.x86    |    Ahh, the lost art of x86 assembly    |    4,675 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 4,612 of 4,675    |
|    Frederick Virchanza Gotham to All    |
|    aarch64 (64-Bit ARM) - return by value -    |
|    17 Jul 23 07:21:34    |
   
   From: cauldwell.thomas@nospicedham.gmail.com   
      
   I realise this newsgroup has x86 in its name but I'm finding it difficult to   
   find a decent ARM assembler group online. I figure someone here might be able   
   to program in aarch64 assembler as well as x86.   
      
   I'm trying to write a very simple function in two or three aarch64   
   instructions as 'inline assembler' inside a C++ source file.   
      
   With the aarch64 calling convention on Linux, if a function returns a very   
   large struct by value, then the address of where to store the return value is   
   passed in the X8 register. This is out of the ordinary as far as calling   
   conventions go. Every other    
   calling convention, for example System V x86_64, Microsoft x64, cdecl,   
   stdcall, arm32, pass the address of the return value in the first parameter.   
   So for example with x86_64 on Linux, the RDI register contains the address of   
   where to store the very    
   large struct.   
      
   I want to try emulate this behaviour on aarch64 on Linux. When my assembler   
   function is entered, I want it to do two things:   
   (1) Put the address of the indirect return object into the first parameter   
   register, i.e. move X8 to X0   
   (2) Jump to a location specified by a global function pointer   
      
   So here's how I think my assembler function should look:   
      
    __asm("Invoke: \n"   
    " mov x0, x8 \n" // move return value address into 1st parameter   
    " mov x9, f \n" // Load address of code into register   
    " br x9 \n" // Jump to code   
    );   
      
   I don't know what's wrong here but it doesn't work. In the following complete   
   C++ program, I use the class 'std::mutex' as it's a good example of a class   
   that can't be copied or moved (I am relying on mandatory Return Value   
   Optimisation).   
      
   Here is my entire program in one C++ file, could someone please help me write   
   the assembler function properly? Am I supposed to be using the ADRP and LDR   
   instructions instead of MOV?   
      
   #include
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca