Home > Mobile >  PeekInt, PokeInt, Peek, Poke equivalent in C from BASIC
PeekInt, PokeInt, Peek, Poke equivalent in C from BASIC

Time:06-27

I was wondering what is the equivalent of the command Peek and Poke (Basic and other variants) in C. Something like PeekInt, PokeInt (integer).

Something that deals with memory banks, I know in C there are lots of ways to do this and I am trying to port a Basic program to C.

Is this just using pointers? Do I have to use malloc?

CodePudding user response:

Yes, its exactly pointers.

  • to read from the location pointed by some pointer code value = *pointer. (peek)
  • to write to that location, code *pointer = value. (poke)

notice the asterisk sign before pointer.

malloc is used when you need to allocate runtime memory in heap, but its not the only way to get a memory pointer. you can get a pointer simply by using & before name of a variable.

int value = 2;
int *myPointer = &value;

remember to free any memory allocated with malloc after you are done with it. See also the valgrind tool.

also I recommend to stick with non malloc solution because of its simplicity and easy maintenance.

you can call a function many time to allocate new memory for its local variables and work with them.

CodePudding user response:

The concept of peek/poke (to directly access memory) in C is irrelevant - you probably don't need them and if you do you really should ask a specific question about the code you are trying to write. If you are building 32 or 64 bit code for a modern platform, peek() / poke() are largely irrelevant in any event and unlikely to do what you expect - unless you expect a memory protection fault! You will be digging out some antique compiler if you are building 16-bit x86 "real-mode" code.

C is a systems-level language and as such operating directly on memory fundamental to the language. It is also a compiled rather than interpreted language and you would normally access a memory location through a variable/symbol and let the linker resolve/locate its address. However in some cases (in embedded systems code or kernel level device drivers for example) you might need to access a specific physical address which you might do as follows:

#include <stdint.h>
const uint16_t* const KEYBOARD_STATE_FLAGS_ADDR = ((uint16_t*)0x0417) ;

...

// Peek keyboard state
keyboard_flags = *KEYBOARD_STATE_FLAGS_ADDR  ;

If you really want functions to observe/modify arbitrary address locations then for example:

uint16_t peek16( uint32_t addr )
{
    return *((uint16_t*)addr) ;
}

void poke16( uint32_t addr, uint16_t value )
{
    *((uint16_t*)addr) = value ;
}

... and perhaps corresponding implementations for 8, 32 and even 64 bit access. However good luck avoiding a SEG-FAULT exception on a modern system where memory is virtualised and protected - as I said it largely makes no sense.

Something that deals with memory banks,

I assume given the [qbasic] tag that you are referring to 16-bit x86 segment:offset addressing rather than "memory banks" - that is an architecture specific thing, irrelevant on modern systems. If you really need to deal with that (i.e. are targeting 16-bit x86 C code), you need to mention that - it is a very different issue, specific to a particular obsolete architecture. You would also need to specify what compiler you are using, because it involves non-standard compiler extensions (and to be frank, techniques I have long forgotten; it would be software archaeology).

Is this just using pointers?

Essentially yes, in C pointers are addresses, but in 16-Bit x86 code there is the added complication of the segmented memory architecture and the concept of near and far pointers. If you are porting this code to a modern system, it is unlikely to be a simple matter of porting peek/poke commands verbatim - they are unlikely to work. If you are are just translating 16-bit QBasic code to 16-bit C - why?!

Do I have to use malloc?

No - or at least that depends on the semantics of the code you are porting, but unlikely, and it is not relevant to peek/poke specifically. malloc allocates memory from a system heap and provides its address - which is non-deterministic. peek/poke are a means of accessing specific memory addresses.

In the end it is probably not a matter of directly implementing the peek/poke commands in the code you are porting, and whether that would work or not would depend on the platform and architecture you are porting the code to. Most likely you would be better off looking at the higher level semantics of the code you are porting and implementing that in a manner that suits the platform you are targeting or better be platform independent and therefore portable.

Basically when porting you should ask your self what does this bit of code do, and port that rather than a line-by-line translation. And that consideration should be done at as high a level as possible to make the best use of the target language an/or its library. peek/poke were typically used for either accessing machine features no exposed through some higher lever interface, or for directly accessing hardware or video-buffers. On a modern platform much of that is either unnecessary or won't work - and probably both.

CodePudding user response:

Yes, you will have to use pointers. No, it does not necessarily involve malloc.

If you have a memory address ADDRESS and you want to poke a byte value into it, in C that's

char *bytepointer = ADDRESS;
*bytepointer = bytevalue;

As a concrete example, to poke the byte value 0h12 to memory address 0h3456, that would look like

char *bytepointer = 0x3456;
*bytepointer = 0x12;

If on the other hand you want to poke in an int value, that looks like

int *intpointer = ADDRESS;
*intpointer = intvalue;

"Peeking" is similar:

char fetched_byte_value = *bytepointer;
char fetched_int_value = *intpointer;

What's happening here is basically that these pointer variables like bytepointer and intpointer contain memory addresses, and the * operator accesses the value that the pointer variable points to. And this "access" can be either for the purpose of fetching (aka "peeking"), or storing ("poking").

See also question 19.25 in the C FAQ list.

Now, with that said, I have two cautions for you:

  1. Pointers are an important but rather deep concept in C, and they can be tricky to understand at first. If you've never used a pointer, if you haven't gotten to the Pointers chapter in a good C textbook, the superficial introduction I've given you here isn't going to be enough, and there are all sorts of pitfalls waiting for you if you don't learn about them first.

  2. Setting a pointer to point to an absolute, numeric memory address, and then accessing that location, is a low-level, high-powered technique that ends up being rather rare these days. It's useful (and still commonly used) if you're doing embedded programming, if you're using a microcontroller to access some hardware, or perhaps if you're writing an operating system. In more ordinary, "applications" level programming, on the other hand, there just aren't any memory addresses which you're allowed to access in this way.

What values do you want to peek or poke, to accomplish what? What is that Basic program supposed to do? If you're trying to, for example, poke values into display memory so they show up on the screen, beware that on a modern operating system (that is, anything newer than MS-DOS), it doesn't work that way any more.

  • Related