Peeking and Poking with Pointers

Back in the microcomputer days, hobbyists used the BASIC language to program their proto-PCs. BASIC is easy to learn, sloppy and forgiving. It also hints at some low-level language attributes, primarily with the PEEK and POKE commands.

The PEEK command returned the byte value at a memory location.

The POKE command allowed you to set the value of a memory location.

These commands should terrify you now, but in the realm of a single-user, single-tasking computer, they were fun. For the Apple II, a poster-sized sheet of “Peeks and Pokes” (PDF) was available. Use the values and BASIC commands listed to alter your computer’s function, change default settings, and generally have fun.

On a modern computer, memory is protected — specifically to avoid malicious programs or curious programmers from altering a balanced and busy system. Yet, the C language has equivalents to the old peek and poke commands. You know them as pointers.

For example, if you were running an Apple II and wanted to click the speaker, in BASIC you’d type PEEK($C030). The C language equivalent might be:

char *p,a;

p = (char *)0xc030;
a = *p;

Above, p is a char pointer and it’s set to the direct memory value 0xc030. This statement is illegal in current implementations of C, as you can only assign a pointer to a compatible variable. But I remember doing similar coding back in the 1980s. Then, to access that “peek” location, you assign the value stored at p to char variable a. This approach might work, and if anyone has a runnning Apple II with a C compiler, they could confirm it. The odds of that happening are rather low.

Today, the peeking and poking you do with pointers is limited to the realm of memory assigned to your program. (The operating system’s API might have a method to access other memory locations, but such a discussion is beyond the scope of this post.)

In Code:Blocks, start a new Project, Console Application, C language.

Give the project a title, Peeks and Pokes. And check the box to Create Debug Configuration. You can leave the Release Configuration box unchecked.

Type the following code for main.c:

int main()
    short *p;
    short a;

    a = 65;
    p = &a;

    return 0;

This code generates no output, which is why you don’t need the stdio.h header file. Instead, this code is meant to be debugged, which shows you (peeks) at what’s going on in memory.

Build and run the code. You can ignore any unused variable warnings.

Now you debug:

Click Line 5 to place the cursor at that location. On the Debugger toolbar, shown in Figure 1, click the Run to Cursor button outlined in blue in the figure. If you don’t see the Debugger toolbar, choose View, Toolbars, Debugger.

Figure 1. Code:Blocks’ Debugging toolbar.

After you click the Run to Cursor button, you see a flurry of activity. Click the Debugging Windows button, outlined in green in Figure 1, and choose Watches from the menu. You see the Watches window appear, which lists the code’s variables, similar to what’s shown in Figure 2.

Figure 2. The Watches window shows you variables used in your code.

The first column shows the code’s variable names. The second column shows their values. At this point in the code (Line 5), the variables are uninitialized. The values shown are whatever garbage already exists in memory. And, yes, this garbage is why it’s important in C to always initialize your variables.

On the Debugging toolbar, click the Next Line button, which is just to the right of the Run to Cursor button on the Debugging toolbar.

You see the value for variable a set to 65.

When you click the Next Line button again, you see the memory location of variable a assigned to pointer p. On my screen, the value is 0x60ff0a. At that precise memory location in my computer, the short int value 65 sits and waits.

The program is over, co click the red X button on the Debugging toolbar to exit the debugger and stop.

In next week’s Lesson, I’ll show you a memory map where you can view the value and marvel at its brilliance.

3 thoughts on “Peeking and Poking with Pointers

  1. We used to use poke a lot with the ZX81 to speed up graphics and particularly animation. Each character position had a memory address which you could poke a value into to set the character directly, which was way faster than printing. I can’t remember the character set used, it might have been ASCII plus some sort of extended ASCII, but knowing Sinclair they probably invented their own.

    There was a piece on the news the other day that the Sinclair designer has just died.

  2. This is nothing to do with your post, but anybody who has The C Programming Language by Kernighan & Ritchie might like to look up recursion in the index 🙂

Leave a Reply