C
C言語
Z80

ハイテク C コンパイラで (a == 1 && a == 2 && a == 3) を常に真にする

はじめに

HOGE.C
#include <stdio.h>

int main(void)
{
    long a = 0;

    if (a == 1 && a == 2 && a == 3) {
        puts("true");
    } else {
        puts("false");
    }
    return 0;
}

をコンパイル、実行して常に true を出力したい。

hitechc.png

解説

インチキくさいことをしています。コマンドラインにある piyo.as がそれです。
今回使用した HI-TECH C COMPILER (CP/M-80) V3.09 で前述のソースをコンパイルすると出力コードは以下の内容となりますが

global  _main
global  ncsv, cret, indir
global  arelop
global  arelop
global  arelop
global  _puts
psect   text
_main:
global csv
call csv
push hl
push hl
ld  (ix+-4),0
ld  (ix+-3),0
ld  (ix+-2),0
ld  (ix+-1),0
ld  de,1
ld  hl,0
push    hl
push    de
ld  e,(ix+-4)
ld  d,(ix+-3)
ld  l,(ix+-2)
ld  h,(ix+-1)
call    arelop
jp  nz,l3
ld  de,2
ld  hl,0
push    hl
push    de
ld  e,(ix+-4)
ld  d,(ix+-3)
ld  l,(ix+-2)
ld  h,(ix+-1)
call    arelop
jp  nz,l3
ld  de,3
ld  hl,0
push    hl
push    de
ld  e,(ix+-4)
ld  d,(ix+-3)
ld  l,(ix+-2)
ld  h,(ix+-1)
call    arelop
jp  nz,l3
ld  hl,19f
push    hl
call    _puts
pop bc
jp  l4
l3:
ld  hl,29f
push    hl
call    _puts
pop bc
l4:
ld  hl,0
jp  cret
psect   data
19:
defb    116,114,117,101,0
29:
defb    102,97,108,115,101,0
psect   text

long 同士の値の比較に arelop というサブルーチンが呼ばれていることがわかります。もしこれが常に「等しい」という結果を返せば (a == 1 && a == 2 && a == 3) は真となることが予想できます。それをするための arelop の置き換えが以下です。

PIYO.AS
        psect   text
        global  arelop
arelop:
        cp      a
        pop     hl
        pop     de
        ex      (sp), hl
        ret

勿論これをリンクしなければ long 同士の比較は普通に行われるので前述のプログラムは false を返すこととなります。

hitechc2.png

終わりに

終わりです。