低レイヤを知りたい人のためのCコンパイラ作成入門(ステップ2)

www.sigbus.info

.intel_syntax noprefix
.globl main
main:
  mov rax, 5
  add rax, 20
  sub rax, 4
  ret
$ cc -g -o tmp tmp.s
$ gdb ./tmp
(gdb) b main
Breakpoint 1 at 0x1125: file tmp.s, line 4.
(gdb) r
Starting program:

Breakpoint 1, main () at tmp.s:4
4         mov rax, 5
(gdb) n
5         add rax, 20
(gdb) p $rax
$1 = 5
(gdb) n
6         sub rax, 4
(gdb) p $rax
$2 = 25
(gdb) n
main () at tmp.s:7
7         ret
(gdb) p $rax
$3 = 21
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  if (argc != 2) {
    fprintf(stderr, "引数の個数が正しくありません\n");
    return 1;
  }

  char *p = argv[1];

  printf(".intel_syntax noprefix\n");
  printf(".globl main\n");
  printf("main:\n");
  printf("  mov rax, %ld\n", strtol(p, &p, 10));

  while (*p) {
    if (*p == '+') {
      p++;
      printf("  add rax, %ld\n", strtol(p, &p, 10));
      continue;
    }

    if (*p == '-') {
      p++;
      printf("  sub rax, %ld\n", strtol(p, &p, 10));
      continue;
    }

    fprintf(stderr, "予期しない文字です: '%c'\n", *p);
    return 1;
  }
  printf("  ret\n");
  return 0;
}
$ gdb ./9cc
(gdb) b main
Breakpoint 1 at 0x401bac: file 9cc.c, line 5.
(gdb) r '5+20-4'
Starting program: /home/yoshio/rui_ueyama/9cc/9cc '5+20-4'

Breakpoint 1, main (argc=2, argv=0x7fffffffdfe8) at 9cc.c:5
5         if (argc != 2) {
(gdb) n
10        char *p = argv[1];
(gdb) 
12        printf(".intel_syntax noprefix\n");
(gdb) p p
$1 = 0x7fffffffe389 "5+20-4"
(gdb) n
.intel_syntax noprefix
13        printf(".globl main\n");
(gdb) 
.globl main
14        printf("main:\n");
(gdb) 
main:
15        printf("  mov rax, %ld\n", strtol(p, &p, 10));
(gdb) 
  mov rax, 5
17        while (*p) {
(gdb) p p
$2 = 0x7fffffffe38a "+20-4"
(gdb) n
18          if (*p == '+') {
(gdb) 
19            p++;
(gdb) 
20            printf("  add rax, %ld\n", strtol(p, &p, 10));
(gdb) p p
$3 = 0x7fffffffe38b "20-4"
(gdb) n
  add rax, 20
21            continue;
(gdb) p p
$4 = 0x7fffffffe38d "-4"
(gdb) n
17        while (*p) {
(gdb) 
18          if (*p == '+') {
(gdb) 
24          if (*p == '-') {
(gdb) 
25            p++;
(gdb) 
26            printf("  sub rax, %ld\n", strtol(p, &p, 10));
(gdb) p p
$5 = 0x7fffffffe38e "4"
(gdb) n
  sub rax, 4
27            continue;
(gdb) p p
$6 = 0x7fffffffe38f ""
(gdb) n
17        while (*p) {
(gdb) 
33        printf("  ret\n");
(gdb) 
  ret
34        return 0;
(gdb) 
35      }
(gdb)