![](/img/trans.png)
[英]Rewriting GCC inline assembly to not require volatile or a memory clobber
[英]Rewriting generated assembly into GCC inline assembly
在CI中有:
struct segv_ctrl {
_Bool volatile*volatile rfaulted_eh_ptr;
_Bool volatile*volatile wfaulted_eh_ptr;
};
_Thread_local struct segv_ctrl segv_ctrl;
_Bool rfaulted_eh(char volatile*Ptr)
{
_Bool volatile faulted=0;
char c; _Bool r;
segv_ctrl.rfaulted_eh_ptr = &faulted;
#if 1
c=*Ptr;
r = faulted;
#else
//I'd like this to produce the same code as the #if block above
//but I obviously have no idea what I'm doing :D
__asm__ __volatile__ (
"mov (%2),%0;\n"
"mov %3,%1;\n"
: "=r"(c), "=r"(r)
: "r" (Ptr), "r"(faulted)
);
#endif
return r;
}
_Bool wfaulted_eh(char volatile*Ptr)
{
_Bool volatile faulted=0;
_Bool r;
segv_ctrl.wfaulted_eh_ptr = &faulted;
#if 1
*Ptr=0;
r = faulted;
#else
#endif
return r;
}
在x86-64上使用從-O1到-O3的clang,它非常可靠地生成:
c.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <rfaulted_eh>:
0: c6 44 24 ff 00 movb $0x0,-0x1(%rsp)
5: 48 8d 44 24 ff lea -0x1(%rsp),%rax
a: 64 48 89 04 25 00 00 mov %rax,%fs:0x0
11: 00 00
13: 8a 07 mov (%rdi),%al
15: 8a 44 24 ff mov -0x1(%rsp),%al
19: c3 retq
1a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
0000000000000020 <wfaulted_eh>:
20: c6 44 24 ff 00 movb $0x0,-0x1(%rsp)
25: 48 8d 44 24 ff lea -0x1(%rsp),%rax
2a: 64 48 89 04 25 00 00 mov %rax,%fs:0x0
31: 00 00
33: c6 07 00 movb $0x0,(%rdi)
36: 8a 44 24 ff mov -0x1(%rsp),%al
3a: c3 retq
我想拿
mov (%rdi),%al
mov -0x1(%rsp),%al
部分和
movb $0x0,(%rdi)
mov -0x1(%rsp),%al
零件,然后將它們變成可重復使用的,可插入的匯編摘要。
我非常失敗的嘗試顯示在上面省略的#if塊中。 您能否解釋為什么這是錯誤的,並且可以通過內聯匯編實現此功能?
(我正在使用它廉價地檢測段錯誤(如果不會出現段錯誤)。如果我知道可能的段錯誤指令的長度,則可以在我的SIGSEGV處理程序中跳過它,而不必花費相當大的代價sigsetjmp,但gcc不會生成如此可靠的代碼,因此我想強制執行。)
第二行只是從堆棧中加載faulted
,您不需要在asm中加載它,它也永遠不會faulted
(假設以前的初始化沒有faulted
)。 您可以使用
"mov (%1), %0" : "=a" (c) : "D" (Ptr)
和
"movb $0, (%1)" : "=m" (*Ptr): "D" (Ptr)
其中a
是rax
適當大小的子寄存器,對於8位為al
。 D
是rdi
寄存器。 =
表示輸出。 m
是一個通用的內存操作數,用於告訴編譯器asm正在*Ptr
處寫入內存。 由於您的Ptr
是volatile
因此可以在此處省略,這樣編譯器將不會緩存該值,但不會造成損害。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.