環境
- WSL / Ubuntu
hello, world
fig1.s
# Assembly (as, x64, Linux)
# as -al -o fig1.o fig1.s
# ld -o fig1 fig1.o
.intel_syntax noprefix
.equ sys_write, 1
.equ sys_exit, 60
.section .rodata
msg: .ascii "hello, world\n"
.equ len, $ - msg
.text
.global _start
_start:
mov edx, len
lea rsi, msg
mov edi, 1 # stdout
mov eax, sys_write
syscall
xor edi, edi
mov eax, sys_exit
syscall
fig1b.s
Cコンパイラで-Sオプションを付けてアセンブリリスト(.s)を出力すると参考になる。
fig2.c
// cc -S -fno-asynchronous-unwind-tables -masm=intel -O2 fig2.c
// cc -o fig2 fig2.c
const char msg[6] = "hello\n";
void main(void)
{
write(1, msg, 6);
}
アセンブリからCライブラリ関数を呼ぶ
fig3.s
# as -al -o fig3.o fig3.s
# cc -o fig3 fig3.o
.intel_syntax noprefix
.section .rodata
msg: .asciz "hello, %d\n"
.text
.global main
main:
sub rsp, 8
mov esi, 42
lea rdi, msg[rip]
xor eax, eax
call printf
xor eax, eax
add rsp, 8
ret
Cからアセンブリ関数を呼ぶ
fig4.c
// cc -o fig4 fig4.c fig4a.s
#include <stdio.h>
int hoge(int);
int main(void)
{
printf("%d\n", hoge(42));
}
fig4a.s
.intel_syntax noprefix
.text
.global hoge
hoge:
mov eax, edi
add eax, eax
ret
インライン・アセンブラ
fig5.c
// C (gcc) -masm=intel
// cc -masm=intel -o fig5 fig5.c
#include <stdio.h>
// 戻り値:rax
// 引数:rdi rsi rdx rcx r8 r9
// 退避:rbx rbp rsp r12-r15
int hoge(int a, int *b, int *c, int *d)
{
__asm__("\
push rbx ;\
mov r8, rcx ;\
mov r9, rdx ;\
mov eax, edi ;\
cpuid ;\
mov [rsi], ebx ;\
mov [r9], ecx ;\
mov [r8], edx ;\
pop rbx ;\
");
}
int main(void)
{
for (int i = 0x80000002; i <= 0x80000004; i++) {
int b, c, d;
int a = hoge(i, &b, &c, &d);
printf("[%.4s%.4s%.4s%.4s]\n",
(char *)&a, (char *)&b, (char *)&c, (char *)&d);
}
}