2

Below is my code. Please note that I am not running this code on a normal machine, but on an architecture simulator (gem5).

#include <stdio.h>
int main() 
{
   int *p;
   int x;
   p = &x;
   p[0] = 3;
   // *(0xffff) = 6;
   return 0;
}

If I uncomment the line, I get a compiler error (which is expected) "indirection requires pointer operand". Since I am not running it on an actual machine, but on a simulator, I have control over how the hardware behaves, and the address space. I want to store value 6 in address 0xffff. One way to do this is:

int *p;
p = (int *)0xffff;
p[0] = 6;

Please note that this will not result in a segmentation fault for me, because I am running it on a simulator, and I control the address space. But, this is an inefficient way, because every time variable 'p' should be accessed, get 0xffff, and then store 6. Accessing variable 'p' even if declared as register, will take 1 cycle which is costly for me in the long run. Since I know 'p' will always have 0xffff, can't I write something like

*(0xffff) = 3;

How do I allow the compiler to generate this code? Any pointers will be of help.

  • 4
    As you said, "*Any pointers will be of help*" – juanchopanza Oct 31 '17 at 23:05
  • This isn't a C-problem, per-se, it is an OS issue and virtual memory manager issue. Modern OS's don't allow Real Mode memory access. (granted some APIs do for specialized hardware, graphics, etc.) But from a secure-computing standpoint, the last two decades of progress have been designed to prevent exactly this type of direct access in favor of Protected Mode where you interact with a hardware API instead of the hardware. Can you set [Real mode](https://en.wikipedia.org/wiki/Real_mode) in your simulator and where the user-space addressing starts? – David C. Rankin Oct 31 '17 at 23:31
  • 1
    A compiler with optimizations enabled will avoid storing the value of the `p` variable if possible. You shouldn't perform such micro-optimizations unless you have seen the generated assembly and know that there is a better way. – interjay Oct 31 '17 at 23:44
  • @David C. Rankin now all programs run in hosted environment. 99% of my ones do not (I do mostly the bare metal embedded projects). – 0___________ Nov 01 '17 at 00:01
  • Yes, I see the need and benefit, especially for embedded systems. It is a ironic how much effort was spent trying to prevent real mode addressing just to find the need reemerge as software begins running on more and more devices and serving different purposes. It wasn't that long ago you had to shuffle punch-cards into a card reader just to get a FORTRAN program to run.... – David C. Rankin Nov 01 '17 at 03:03

2 Answers2

2

I don't know if you can do it without a pointer at all, but if you don't want to declare a pointer on a separate line, you could do this:

*(int*)(0xffff) = 3;
Dan Korn
  • 1,274
  • 9
  • 14
0

If you are concerned with the extra cycles, you can use some inline assembly. Typically, the MOV instruction (MOV r/m32, imm32) allows you to move the immediate value into the register, or into the address pointed to by the register. If you wish to bypass the use of the register completely, you could use the C6 instruction (from this post).

  c6        04         25      0xffff     3
  opcode    modr/m     sib     address    immediate

Assuming you are using an x86 architecture, you can include that instruction in inline assembly in your source file.

vasia
  • 1,093
  • 7
  • 18
  • 1
    A decent optimizing compiler will automatically use the best instruction for the job. There's no reason to use inline assembly for this. – interjay Oct 31 '17 at 23:42
  • You are right, I didn't know it was so easy to do it directly. – vasia Oct 31 '17 at 23:51