0

I'm trying to declare a static const data using asm syntax inside of a struct.

Maybe something like this?

struct Z
{
  public:
    static char hello[] = asm volatile(".ascii \"Hello\"");
};

Note that this does not come even close to working. :) And my assembly is super rusty.

EDIT:

For those interested in this question and the reasons behind it, please see store non-nul terminated C string constant in C++.

This question was tangential and I didn't want to clutter that question up with it as well as it could have other uses beyond what I wanted it for which is why I started up a separate question.

Thanks for your interest and help.

Community
  • 1
  • 1
Adrian
  • 10,246
  • 4
  • 44
  • 110
  • 5
    Uhm... what are you trying to do? In other words, what's your goal in doing this, that doing `static char hello[];` and then `char Z::hello[] = "\"Hello\"";` somewhere outside the struct won't achieve? – Nik Bougalis May 10 '13 at 16:56
  • 1
    I am not even sure `asm` can appear in an expression in any known compiler. – Morwenn May 10 '13 at 17:01
  • gcc, g++. Trying to make a string literal without a terminating NUL. I'm not really wanting to do this using the asm, but I thought i might do for short term. Please don't say, "Don't do that". If you want more info as to my rational, see here: http://stackoverflow.com/questions/16483536/store-non-nul-terminated-c-string-constant-in-c?noredirect=1#comment23655428_16483536 – Adrian May 10 '13 at 17:06
  • @Adrian: So I take it your strings are stored in a different chunk of memory, that is more restrictive, than your code memory, since `sizeof(x)` will definitely take more bytes of code-space than storing a zero at the end of each string.This is the motivation for using zero termination in the first place. – Mats Petersson May 10 '13 at 17:28
  • @MatsPetersson: ??? sizeof(x) takes no runtime memory. It generates a compile time constant. – Adrian May 10 '13 at 17:33
  • 1
    @Adrian: I'm not entirely sure what you mean there, because someplace you need to know the size of each string, which will take some space in the code. Unless I've not understood what you are actually doing. Calling strlen in one central place is most likely shorter than passing along the size with each string from the code that uses the string, is what I'm trying to say. But since you haven't actually posted any code USING the strings, it's hard to give advice. I'm just saying the "zero at the end" is a way to save space, compared to "knowing the length". – Mats Petersson May 10 '13 at 17:38
  • That may be true in some cases. But not in this one. I'm sorry if I'm being vague, but there are specifics that I haven't gotten into. Details like sizes being stored in bit fields instead of whole bytes would allow for it to be smaller than a NUL char. I'm running on a platform that has a very restricted memory model, a micro-controller, so every byte is precious. – Adrian May 10 '13 at 17:59
  • @Adrian: If that is the case, have you considered preprocessing the strings themselves and storing the whole string in, perhaps, 6 bits? That would save you more space altogether. But it would require a bit of mucking about, but I suspect you are already doing something like calling a function to get a certain string, or some such? – Mats Petersson May 10 '13 at 19:29
  • @MatsPetersson, I'm thinking you are mocking me, but you may be talking about compression, so I'll give you the benefit of the doubt. Yes, there will be an interface to get the strings, but the strings are more for those on the other end of the serial communication port. – Adrian May 10 '13 at 19:41
  • @MatsPetersson and others, I'd like it if you wish to continue to help to move to the other question. This question is a dead end. – Adrian May 10 '13 at 19:48

3 Answers3

3

No, not like this. You can make inline assembly if your compiler supports it, however. Another common (and likewise non-portable) technique is to use an assembler to assemble the code to raw machine code, then wrap it into a byte array (you can see this in action in various kinds of shellcode where the payload is stored like this).

  • "raw machine code, then wrap it into a byte array" could you explain that a bit? – Koushik Shetty May 10 '13 at 17:00
  • 4
    @Koushikn `unsigned char boom[] = "\xaf\x3c\x02\x90";` –  May 10 '13 at 17:01
  • 1
    @Koushik Use an assembler to generate a series of CPU instructions (which will be in binary), then place those in a byte array in hexadecimal. `\x90\x90`, etc.. – Hunter McMillen May 10 '13 at 17:01
  • you mean copy paste right? becuase my confusion is around programatically doing it or not. – Koushik Shetty May 10 '13 at 17:02
  • No, I'm looking for a way of generating a string of bytes that is not null terminated in C++. Looks like another dead end – Adrian May 10 '13 at 17:03
  • @Adrian Why not use a normal string and store its size explicitly? –  May 10 '13 at 17:07
  • I'm assuming you mean char hello[5]="hello"? Not valid C++. – Adrian May 10 '13 at 17:08
  • I'm thinking that this is a dead end anyway. I need to get the bytes from the string into a template parameter list so I can generate the array of bytes explicitly or I'll have padding issues. – Adrian May 10 '13 at 17:09
  • @Adrian No, I don't mean that. I mean `const char *hello = "hello"; const size_t hello_len = 5;` - why does poor NUL terminator disturb you? –  May 10 '13 at 17:10
  • @H2CO3: BTW, your answer is cute. Haven't seen that since scripting in AHK. :) – Adrian May 10 '13 at 17:11
  • See the url in the comments in the question. – Adrian May 10 '13 at 17:12
  • @Adrian What do you mean by that? Are you referring to my last comment? –  May 10 '13 at 17:13
  • I have just posted a solution that I believe does exactly what you want. – Mats Petersson May 10 '13 at 17:17
  • @Adrian: `unsigned char x86nop[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }` will give you an array of 27 bytes, each with an x86 `nop` opcode and no null-terminator. – Nik Bougalis May 10 '13 at 17:18
  • @H2CO3 mean by what? The url? It is the reason why I wanted this in the first place and I don't want to repeat it as it is more general. This question was highly specific. – Adrian May 10 '13 at 18:43
  • @Adrian You wrote "BTW, your answer is cute. Haven't seen that since scripting in AHK" - I didn't understand what part you were talking about. –  May 10 '13 at 18:44
  • @NikBougalis Yes it does... so... what are you trying to say? – Adrian May 10 '13 at 18:44
  • @H2CO3 Ah, I've seen doing that in another forum where you can run assembled code from a scripting language called AutoHotkey (AHK). It has some limited applications, but it is quite cool in that domain. :) – Adrian May 10 '13 at 18:46
  • @Adrian Ah, OK, I see now. :) –  May 10 '13 at 18:51
  • @Adrian I'm saying that I don't see what you're trying to achieve that cannot be achieved using such arrays. – Nik Bougalis May 10 '13 at 19:03
  • @NikBougalis specific data layout. I'd like to have some bytes, then a string **without** a NUL, then more bytes. It's all in the other question. – Adrian May 10 '13 at 19:15
  • @Adrian: `unsigned char x86nop[] = { 0x90, 0x90, 0x90, 'H', 'e', 'l', 'l', 'o', 0x90, 0x90, 0x90 };` Some bytes, a string without a NUL then more bytes. – Nik Bougalis May 10 '13 at 19:30
  • Too clumsy, obfuscates and detracts from what I am trying to express in the language. Being able to use a string literal is key. I thank you for your attempts at helping me, but if you want to continue trying to help, please go to the other question I posted. This question has no more relevance. Thanks. – Adrian May 10 '13 at 19:46
2

You comment says you want to "generate a string of bytes that is not null terminated". That is easy, use

char hello[] = { 'H', 'e', 'l', 'l', 'o' };
brian beuning
  • 2,836
  • 18
  • 22
  • No. This doesn't even come close to answering the question. – Adrian May 10 '13 at 17:14
  • @Adrian why? You're not giving us a lot to go on. – Nik Bougalis May 10 '13 at 17:16
  • The question was fairly specific. If you want to know my rational, please see: http://stackoverflow.com/questions/16483536/store-non-nul-terminated-c-string-constant-in-c – Adrian May 10 '13 at 17:17
  • 2
    @Adrian No. The question was vague and unclear. I want to understand why the solution shown here doesn't work for your purposes. – Nik Bougalis May 10 '13 at 17:19
  • @NikBougalis: The question was specific. I wanted to know if I could put an assembly instruction inside of a struct to represent static data. It has been answered as no. My purposes can be found at the other question. – Adrian May 10 '13 at 17:29
2

Assuming you know (or can count) the size of the string:

 char hello[5] = "Hello";

will do exactly what you want.

You could also do a macro, like this:

#define STR(x, y)   const char x[sizeof(y)-1] = y

This works for me:

#include <stdio.h>

#define STR(x, y)   const char x[sizeof(y)-1] = y

STR(hello, "Hello");
STR(hello2, "Hello World");
STR(hello3, "Hello kerflunk");

#define PRINT(x) printf("size " #x "=%zd\n", sizeof(x));

int main()
{
    STR(bar, "Bar");

    PRINT(hello);
    PRINT(hello2);
    PRINT(hello3);
    PRINT(bar);

    return 0;
}

Output:

size hello=5
size hello2=11
size hello3=14
size bar=3
Mats Petersson
  • 126,704
  • 14
  • 140
  • 227