0

Edit: I suddenly realized that I can write a C Hello World and look at the disassembled code if I have the tool. I'll see what I get.

I'm trying to write a simple Hello World program using an iBook G4 (Mac OS X with XCode 2.5), assembled by GNU assembler 1.38.

Surprisingly, there is VERY LITTLE material online for this architecture, even compared to CPUs from decades earlier such as 68K (yeah I know it was popular but PowerPC has been popular for a while too). All the IBM links are down, and even archive.org doesn't work because IBM just loves to redirect spiders I guess. There is only the more advanced 64-bit AIX stuff I think. The only book I could find is the "Programming the PowerPC (1994)" but it doesn't talk about assembly programming. There is also the NXP PowerPC 601 manual, but I don't understand it (more details below).

Anyway, I asked ChatGPT to write a program, and wasn't able to compile it after many hours of correcting (For a good laugh, I spent 30 mins convincing myself and ChatGPT that it actually should use ; instead of # for comments -> which I already knew years ago but it happened that the error message was very ambiguous and ChatGPT was so confident of it, so I didn't even think of it in the beginning). Here is the most current version:

.section __TEXT,__text .globl _start _start: # Write "Hello, World!" to stdout li r0, 4 ; System call number: write (Mac syscall table) li r3, 1 ; File descriptor: stdout lis r4, hello@ha ; Load the high part of "hello" address into r4 addi r4, r4, hello@l ; Add the low part to r4 li r5, 14 ; Length of the string sc ; Trigger the syscall # Exit the program li r0, 1 ; System call number: exit (Mac syscall table) li r3, 0 ; Exit status sc ; Trigger the syscall .section __TEXT,__cstring hello: .asciz "Hello, World!\n" 

Error message (for the lis and addi lines):

Parameter error: expression must be absolute (parameter 2) Invalid mnemonic 'ha'

I managed to remove all errors except for the @ha and @l part -- I did find such examples on the Internet (e.g. in the as manual or on Godbolt if I use Power GCC) so I figured maybe it's just a PowerPC error. The NXP manual somehow doesn't even show a load SIMM to Register instruction (looks like all loads look like this: li RA, d(RC)). I think I must have missed something.

Can you please let me know how to correct those two lines? And more importantly, can you please point me to a book or a website for some iBook4 assembly language programming tutorial? Prefer textbooks but manuals work too.

11
  • 3
    There is a PowerPC Hello, World! example on this page and also on this page.CommentedDec 8, 2024 at 23:51
  • 5
    Apple also produced an assembler reference guide for PowerPC and i386 which is relevant to the age of your machine, although it does not have the code examples that you need.CommentedDec 9, 2024 at 0:02
  • 2
    I think this leans towards being one of the “bad” debugging questions.CommentedDec 9, 2024 at 10:07
  • 3
    ... and debugging a program written by ChatGPT, not a human!
    – dave
    CommentedDec 9, 2024 at 13:26
  • 2
    I don't know a PowerPC from a hole in the ground, but 5 minutes googling suggests OSX uses 'ha16' and 'lo16'.
    – dave
    CommentedDec 9, 2024 at 13:31

1 Answer 1

5

The following code works and the ori r0, r0, 0 section stops a segmentation fault after "Hello World" has been printed to the terminal:

.data HelloWorldString: .ascii "Hello World\n" len = . - HelloWorldString .text .globl _start _start: # Load all the arguments for write() li r0, 4 ; syscall number (write) li r3, 1 ; syscall arguments (stdout) lis r4, ha16(HelloWorldString) ; load upper 16 bits of address addi r4, r4, lo16(HelloWorldString) ; add lower 16 bits of address li r5, len ; length of string sc ; call kernel ori r0, r0, 0 ; equivalent to NOP and needed to handle Mac OS system calls correctly # Exit the program li r0, 1 ; syscall number (exit) li r3, 0 ; return status code 0 (program terminated normally) sc ; call kernel 

I then assembled this code with

as -arch ppc helloworld.asm 

and linked it like this

ld -arch ppc -e _start a.out -o helloworld 

Your mileage may vary! I'm assuming the segfault was either a memory issue or I wasn't making the system calls correctly and it was fixed using the example on this page.

6
  • 3
    Mac OS X Internals page 570 explains it. In the libc stubs, the sc is followed by an unconditional call to cerror() which sets errno, ie, sc ; bl cerror If the call succeeds, errno shouldn't be set so srr0 -- the return pc address -- is incremented to skip over that instruction. This is MacOS-specific behavior.CommentedDec 11, 2024 at 17:38
  • 1
    Thank you, that makes sense - that behavior sounds a little bit too clever for its own good, but I see the logic in doing that. So that would presumably mean that the reason my code was segfaulting originally was because li r0, 1 was being skipped over and the following command made no sense when sc was called?CommentedDec 11, 2024 at 18:26
  • 1
    I think the sys call only clobbers r3 and r4 (for the return value), and of course the pc, so if the li r0, 1 would be skipped and you would effectively be doing something like write(0, NULL, 12), then dropping off into who knows what. That's my theory anyway. If you have truss (when was that added?) you could see what syscalls are happening.CommentedDec 11, 2024 at 19:52
  • Thanks. I've no idea how old truss is but it looks like it got replaced by dtruss sometime around OS X 10.5 which is the version I'm running on my G5.CommentedDec 11, 2024 at 20:02
  • 1
    I actually typed dtruss but the auto-correct didn't approve. sudo dtruss *program-name* will print out the systems.CommentedDec 11, 2024 at 22:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.