0
__asm void my_strcpy(const char *src, char *dst){
    
}

__asm void my_capitalize(char *str){
    //Write your code here
}

int main(void){
    const char a[] = "Hello world!";
    char b[20];
    my_strcpy(a, b);
    my_capitalize(b);

    while (1); 
}

So I am using this "skeleton code" to complete this project where I put this code on a Nucleo board and it will print out Hello World and then I use assembly to make it capitalize the text etc. and as I am trying to work on the rest of it I keep getting the error "expected '(' after 'asm'" and "expected ';' after top-level asm block" with anything that I do with it and am not sure what I am doing wrong here.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Eric
  • 11
  • 1
  • 1
    Your usage of the `__asm` keyword looks odd. Where does this code come from? – Jabberwocky Jun 17 '22 at 06:32
  • 2
    Perhaps the feature you are looking for is gcc `__attribute__((naked))` which discards all automatic stacking and you have to hack everything out manually in asm. – Lundin Jun 17 '22 at 06:41
  • This is code that was provided to me for a lab and the code is supposed to work as is when downloaded but throws me this error causing nothing further to be able to be done with it. – Eric Jun 17 '22 at 07:07
  • 1
    @Eric you should probably ask your teacher/tutor and/or read the lab documentation and hope that it contains the required information. – Jabberwocky Jun 17 '22 at 07:09
  • 2
    What compiler are you using? – Gerhard Jun 17 '22 at 09:23
  • 1
    That's not a valid place for the `__asm` keyword in GNU C. It must be followed by parentheses as the error message said. Like `asm("# comment, hi mom" ::: "memory", "r0", "r1");`. https://stackoverflow.com/tags/inline-assembly/info / https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html. Perhaps you're supposed to be using a totally different compiler? I don't know if Keil supports that syntax. – Peter Cordes Jun 17 '22 at 09:28
  • 1
    @Gerhard: you didn't need to delete your answer; after rolling back your edit it's not wrong. Defining a function via a label in a global-scope `asm` statement is almost exactly the same as defining it via `__attribute__((naked)) void my_capitalize(chat *str){ asm("...; bx lr"); }`. My comment about inline asm being not safe if you don't tell the compiler about clobbers *only* applied to its use within non-`naked` functions, where the optimizer can see execution fall into the asm statement, not just a black box with inputs/outputs defined by the calling convention. – Peter Cordes Jun 17 '22 at 10:36
  • @PeterCordes I think this might be part of the issue that I am having is that there is a compiler that we are supposed to be using but as I am on Mac I cannot get that compiler. – Eric Jun 17 '22 at 18:13
  • Where does that skeleton code come from? – Jabberwocky Jun 17 '22 at 19:22
  • 1
    @Eric: Well yes, if you're not using the compiler your assignment is for, you won't be able to use extensions only it supports. Your question doesn't say which compiler you're supposed to be using, although from the error message we can infer that the one you *did* use is GCC or clang. GNU C inline asm syntax is well documented as not being like that. Different compilers support different extensions to ISO C. – Peter Cordes Jun 17 '22 at 21:16

1 Answers1

-1

I am assuming the underlying compiler is GCC.
Forward declare your function as you would in normal C.

void my_capitalize(char *str);

Then implement the function with __asm__( "My Code Here");

__asm__( 
"my_capitalize:\n"
"  mov r0,r0\n"
"  bx lr\n"
);
Gerhard
  • 6,850
  • 8
  • 51
  • 81
  • 1
    You can use `__attribute__((naked))` and put that asm statement (without a label) inside the C function definition. Then you don't have to about toolchains that put a leading `_` on asm symbol names, if any do that for ARM. (Or C++ name mangling, although this is a C question so this will work on normal systems.) – Peter Cordes Jun 17 '22 at 09:32
  • Your last edit introduced a very bad mistake: you used GNU C Basic asm (no input/output/clobber constraints) inside a function that wasn't `__attribute__((naked))`. `mov r0, r0` is a no-op, but anything that modifies registers or memory without telling the compiler about it would be undefined behaviour, and could easily break in practice. Or anything that even reads memory [can't depend on it being in sync](https://stackoverflow.com/q/56432259) with the C abstract machine if you haven't told the compiler or used a `"memory"` clobber. – Peter Cordes Jun 17 '22 at 10:23