LoginSignup
1
1

pomera debian でアセンブラを使いたかった

Posted at

結論

セルフ ビルドの gcc がデフォルトで thumb コードを吐くようなので -marm をつける

現象

アセンブラを含んだ SDL 版アプリをビルドすると、Illegal instruction と怒られる。

調査

.s 呼び出しテスト

単純にアセンブラ コードを呼ぶテスト アプリを作成する

メイク ファイル

Makefile
CXX		=	g++
RM		=	rm -f

TARGET	=	test

CFLAGS	=	-Wall -O3
LFLAGS	=	

CSRCS	=	./test.cpp ./armtest.s

OBJS = $(addsuffix .o, $(basename $(CSRCS)))
LIBS = 

.SUFFIXES: .cpp.o
.SUFFIXES: .s.o

all:	$(TARGET)

$(TARGET):	$(OBJS)
	$(CXX) $(LFLAGS) -g -o $@ $(OBJS) $(LIBS)
	$(STRIP) $@

.cpp.o:
	$(CXX) $(CFLAGS) -c -o $@ $<

.s.o:
	$(CXX) $(CFLAGS)  -c $^ -o $@

clean:
	rm -f $(TARGET) $(OBJS)

マシン語 ファイル
int ArmTest(int v) { return v + 1; }

armtest.s
  .text
  .align 4

	.global ArmTest

ArmTest:
	add	r0, r0, #1
	mov	pc, lr

C コード (main)

test.cpp
#include <stdio.h>

extern "C" int ArmTest(int v);

int main()
{
	 printf("Call ArmTest(2)\n");
	 printf("Result: %d\n", ArmTest(2));
	 return 0;
}

実行結果

実行結果
pomera@pomera:~/temp$ ./test
Call ArmTest(2)
Illegal instruction
pomera@pomera:~/temp$ 

なんで Illegal instruction?

test.cpp のアセンブリコードでは test.o が thumb コードで吐かれていた。
なので解決方法としては:

  1. ARM コード / thumb コードを行き来できるようにする
    • gcc に -mthumb-interwork をオプションをつける
    • .s は bl ではなく bx を利用する
  2. 全部 ARM コードにする
    • gcc に -marm オプションをつける

今回は thumb コードを使わないので 2番にすることで解決。

Makefile
- CFLAGS	=	-Wall -O3
+ CFLAGS	=	-Wall -O3 -marm

実行結果

実行結果
pomera@pomera:~/temp$ ./test
Call ArmTest(2)
Result: 3
pomera@pomera:~/temp$ 
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1