Hier eine Antwort schreiben, da exa eine Prämie ausgestellt hat.
Ich erkannte, dass dies eine etwas alberne Frage nach Ross Ridge's Kommentare war, und einige spielten mit Klängen herum.
Nehmen wir an, wir haben das folgende Programm, das Inline-Assembly verwendet, um write()
direkt aufzurufen.
#include <stdio.h>
int main(void)
{
char *buf = "test\n";
ssize_t n;
asm volatile (
"movl $0x00000002, %%edi\n" /* first argument == stderr */
"movl $0x00000006, %%edx\n" /* third argument == number of bytes */
"movl $1, %%eax\n" /* syscall number == write on amd64 linux */
"syscall\n"
: "=A"(n) /* %rax: return value */
: "S"(buf)); /* %rsi: second argument == address of data to write */
return n;
}
Wir können dies entweder mit kompilieren gcc
oder clang
und etwa das gleiche Ergebnis.
$ gcc -o syscall.gcc syscall.c
$ clang -o syscall.clang syscall.c
$ ./syscall.gcc
test
$ ./syscall.clang
test
Wenn wir die genauen LLVM Anweisungen sehen wollen, die verwendet werden würde, diesen Code zu emittieren, können wir einfach nutzen die -emit-llvm
Flagge. Wie Sie sehen können, gibt es eine call i64 asm sideeffect
Zeile, die die vollständige Inline-Assembly-Zeichenfolge enthält.
$ clang -S -emit-llvm syscall.c
$ cat syscall.ll
; ModuleID = 'syscall.c'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [6 x i8] c"test\0A\00", align 1
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
%buf = alloca i8*, align 8
%n = alloca i64, align 8
store i32 0, i32* %1
store i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i8** %buf, align 8
%2 = load i8** %buf, align 8
%3 = call i64 asm sideeffect "movl $$0x00000002, %edi\0Amovl $$0x00000006, %edx\0Amovl $$1, %eax\0Asyscall\0A", "=A,{si},~{dirflag},~{fpsr},~{flags}"(i8* %2) #1, !srcloc !1
store i64 %3, i64* %n, align 8
%4 = load i64* %n, align 8
%5 = trunc i64 %4 to i32
ret i32 %5
}
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)"}
!1 = metadata !{i32 134, i32 197, i32 259, i32 312}
Gibt es kein relevantes Open-Source-Beispiel, das Sie studieren können? –
Warum nicht Inline-Assembly verwenden, um Systemaufrufe zu tätigen? –
Chris: Nein, das habe ich nicht gefunden. –