2013-03-08 41 views
2

我有一個問題,在彙編中返回errno。我知道如何找到它,但我不能返回errno和返回值。如果我的函數失敗,我會返回errno(由系統調用設置)和-1。 我必須爲學校的學科做這個。我必須在程序集中創建一個小型庫,最後一個函數是「寫入」。我使用call system write,但我也要管理errno。如何在程序集中返回errno?

如果我沒有弄錯,errno是一個全局變量。所以我認爲在裝配中恢復它,並改變它的價值,但我沒有在我的功能中恢復它呢...

我是在好的方式還是完全錯誤的?

我用匯編Intel x86和我編譯與NASM。

對不起,語言錯誤,我不是英語。

回答

3

errno並不總是全局變量。它只是一個左值,可能是一個隱藏函數調用的宏。 the specification

errno是宏還是標識爲外部鏈接的標識符,但未指定。

事實上,它通常是一個全局變量,因爲它通常被實現爲線程本地(因此需要一個函數調用來檢索指向TLS塊)。

你最好有一個調用匯編函數並設置errno的C封裝器。


編輯:既然你不能使用C函數(其中,國際海事組織,是毫無意義的,因爲errno是牢固地固定在C/POSIX的概念),你將不得不實行errno收集自己。在errno.h中查找errno的定義,並執行裝配中的任何內容。例如,我的errno.h定義errno作爲

extern int * __error(void); 
#define errno (*__error()) 

因此,我會做給__error函數的調用(它返回一個int *),然後存儲到返回的地址。例如,這裏是我的系統產生用於設置errno大會:

$ gcc -xc - -o- -S <<EOF 
#include <errno.h> 
main() { errno = 3; return 0; } 
EOF 
    .section __TEXT,__text,regular,pure_instructions 
    .globl _main 
    .align 4, 0x90 
_main: 
Leh_func_begin1: 
    pushq %rbp 
Ltmp0: 
    movq %rsp, %rbp 
Ltmp1: 
    subq $16, %rsp 
Ltmp2: 
    callq ___error 
    movl $3, (%rax) 
     ... 

您的系統可能會有不同的實現的errno

+1

謝謝你的回答,我更瞭解errno現在如何工作。但是我不能在C中使用包裝器,因爲它是一個學校主題,我只能使用匯編代碼。我必須在彙編中做一個小庫(〜10個函數),並且我需要errno作爲最後一個函數。 – Fateske 2013-03-08 23:20:08

+1

埃克,真的嗎?你應該更新你的問題來反映這一點。我會更新答案。 – nneonneo 2013-03-08 23:23:30

+0

我已更新我的問題。我嘗試將你在上次編輯的日記中解釋的內容應用。謝謝你:) – Fateske 2013-03-08 23:36:31

1

如果您只是在裝配中編寫代碼,爲什麼您需要errnoerrno是C庫函數使用的C語言概念,它使系統調用將錯誤返回從這些系統調用返回給C代碼。如果你真的需要它,最簡單的方法是按照nneonneo的描述和編寫一個C函數,獲取地址errno並從你的彙編代碼中調用它。

但是,如果你正在編寫純粹的彙編代碼,你不需要它。系統調用自身在正常返回位置(x86上的eax)返回錯誤代碼,並將其與非錯誤返回區分開來。在Linux中,錯誤始終在-4095 ..- 1範圍內。該範圍內的任何返回值都是錯誤,而超出該範圍的任何值都是非錯誤返回值。在其他UNIX版本(例如* BSD)中,錯誤會設置CARRY標誌。

+0

我需要errno,因爲這些函數(用純彙編代碼編寫)將由C中的函數調用。大多數情況下,我將在C中使用此庫,而不是在彙編代碼中。 – Fateske 2013-03-09 00:30:10

相關問題