2010-06-11 36 views
8

可以訪問C中的32位寄存器嗎?如果是,如何?如果沒有,那麼是否有任何方法將彙編代碼嵌入到C中?順便說一句,我使用MinGW編譯器。 在此先感謝!是否可以訪問C中的32位寄存器?

+1

告訴我們更多關於您的需求:您爲什麼要訪問CPU寄存器? – 2010-06-11 10:46:24

+0

你可以使用GetThreadContext和它的兄弟SetThreadContext間接獲取和設置窗口上的寄存器,不需要任何asm:http://msdn.microsoft.com/en-us/library/ms679362%28VS.85%29.aspx – Necrolis 2010-06-13 07:06:44

回答

12

如果你想只讀寄存器,可以簡單:

register int ecx asm("ecx"); 

顯然,這是依賴於實例化。

另一種方法是使用內聯彙編。例如:

asm("movl %%ecx, %0;" : "=r" (value) :); 

此存儲ecx值入變量value。我已經發布了類似的回答here

+0

非常感謝代碼示例。我需要的確切信息。 ;) – C4theWin 2010-06-11 14:25:27

1

可用在C嵌入組件,其從維基

的extern INT錯誤號

http://en.wikipedia.org/wiki/Inline_assembler

例子;

int funcname(int arg1, int *arg2, int arg3) 
{ 
    int res; 
    __asm__ volatile(
    "int $0x80"  /* make the request to the OS */ 
    : "=a" (res)  /* return result in eax ("a") */ 
     "+b" (arg1),  /* pass arg1 in ebx ("b") */ 
     "+c" (arg2),  /* pass arg2 in ecx ("c") */ 
     "+d" (arg3)  /* pass arg3 in edx ("d") */ 
    : "a" (128)  /* pass system call number in eax ("a") */ 
    : "memory", "cc"); /* announce to the compiler that the memory and condition codes have been modified */ 

    /* The operating system will return a negative value on error; 
    * wrappers return -1 on error and set the errno global variable */ 
    if (-125 <= res && res < 0) { 
    errno = -res; 
    res = -1; 
    } 
    return res; 
} 
0

我不認爲你可以直接做。您可以內聯彙編有類似的代碼:

asm (
    "movl $0, %%ebx;" 
    "movl $1, %%eax;" 
); 
0

如果你是一個32位處理器,並使用適當的編譯器,那麼肯定的。確切的手段取決於你正在編程的特定系統和編譯器,當然這會使你的代碼變得不可移植。

在使用MinGW的情況下,您應該看看GCC's inline assembly syntax

+1

謝謝很多鏈接!很有用。 – C4theWin 2010-06-11 14:20:46

-2

一般不存在需要從寫在一個高級語言的程序訪問CPU寄存器:高級語言,諸如C,Pascal等,其中精確地發明了以抽象底層機器和渲染程序更加機器獨立。

我懷疑你正在嘗試執行某些操作,但不知道如何使用常規方法來執行此操作。

許多對寄存器的訪問都隱藏在更高級別的構造或系統或庫調用中,這樣可以避免編碼「髒部分」。告訴我們更多關於你想做什麼,我們可能會建議你一個替代方案。

+0

不,我確切知道我在做什麼。但是,謝謝你幫助我。 :) – C4theWin 2010-06-11 14:03:09

+0

-1:回答與問題無關。 – Sparky 2010-06-11 14:09:39

0

你當然可以。 「MinGW」(gcc)允許(作爲其他編譯器)內聯彙編,因爲其他答案已經顯示。哪個程序集依賴於系統的CPU(概率是99.99%,它是x86)。然而,這使得你的程序不能在其他處理器上移植(如果你知道你在做什麼以及爲什麼,那就不是那麼糟糕)。

談論gcc的彙編的相關頁面是herehere,如果你願意,也here。不要忘了,它不是特定的,因爲它是依賴於體系結構的(gcc可以編譯爲幾個cpus)

7

你想訪問哪些寄存器?

通用寄存器通常不能從C中訪問。您可以在函數中聲明寄存器變量,但不指定使用哪個特定的寄存器。此外,大多數編譯器會忽略register關鍵字並自動優化寄存器使用情況。

在嵌入式系統中,通常需要訪問外設寄存器(如定時器,DMA控制器,I/O引腳)。這樣的寄存器通常是存儲器映射的,因此它們可以由C被訪問...

通過定義一個指針:

volatile unsigned int *control_register_ptr = (unsigned int*) 0x00000178; 

,或者使用預處理器:

#define control_register (*(unsigned int*) 0x00000178) 

或者,您可以使用匯編程序。

對於使用彙編語言,有(至少)三種可能性:

  1. 與所述節目鏈接的單獨.ASM源文件。像常規函數一樣從C調用匯編例程。這可能是最常用的方法,它具有hw依賴函數與應用程序代碼分開的優點。
  2. 聯機彙編
  3. 執行單個彙編語言指令的內部函數。這具有彙編語言指令可以直接訪問任何C變量的優點。
+0

你怎麼能得到0x00000178號碼? – Garmekain 2016-09-05 17:21:42

相關問題