मेरे पास एक बीएमपी फ़ाइल है और मैं इसे एसी फ़ंक्शन में पढ़ता हूं और पिक्सल के मानों को हस्ताक्षरित पूर्णांक के रूप में संग्रहीत करता हूं। मैं इस अहस्ताक्षरित पूर्णांक सरणी को x86 पर पास करना चाहता हूं लेकिन मैं असफल रहा। यहाँ मेरा सी कोड है:

मेरे पास यह गुण हैं:

extern int func(char *a);
unsigned char* image;

और मेरी मुख्य विधि है:

int main(void){
  image = read_bmp("cur-03.bmp");
  int result = func(image);
  printf("\n%d\n", result);
  return 0;
}

मैं अपनी सरणी की जांच करता हूं और इसमें सही मान हैं।

यहाँ मेरा एनएसएम कोड है:

section .text
global  func

func:
    push ebp
    mov ebp, esp
    mov ecx , DWORD [ebp+8] ;address of *a to eax


    pop ebp
    ret

section .data
    values: TIMES   255         DB      0   

मुझे उम्मीद है कि ecx में मेरी सरणी का पहला तत्व होगा, लेकिन इसके बजाय मुझे 1455843040 मिलता है और शायद पता?

और यहाँ read_bmp है:

unsigned char* read_bmp(char* filename)
{
    int i;
    FILE* f = fopen(filename, "rb");
    unsigned char info[54];
    fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header

    // extract image height and width from header
    int width = *(int*)&info[18];
    int height = *(int*)&info[22];
    int heightSign =1;
    if(height<0){
        heightSign = -1;
    }

    int size = 3 * width * abs(height);
    printf("size is %d\n",size );
    unsigned char* data = malloc(size); // allocate 3 bytes per pixel
    fread(data, sizeof(unsigned char), size, f); // read the rest of the data at once
    fclose(f);

    return data;
}

मेरा अंतिम लक्ष्य सरणी के तत्वों को लेना है (जो 0 - 255 के अंतराल में है) और मेरे 255 बाइट आकार के सरणी में संबंधित मान बढ़ाना है। उदाहरण के लिए यदि मेरी पहली सरणी में पहला तत्व 55 है, तो मैं 255-बाइट-आकार वाले सरणी में 55वें तत्व को एक-एक करके बढ़ाऊंगा। तो मुझे उस सरणी के तत्वों तक पहुंच की आवश्यकता है जिसे मैं सी से पास करता हूं।

-1
vader 25 मई 2019, 14:39

1 उत्तर

सबसे बढ़िया उत्तर

जब आपके पास C प्रोटोटाइप extern int func(char *a); होता है, तो आप स्टैक पर वर्ण सरणी a के लिए एक पॉइंटर पास कर रहे होते हैं। आपका असेंबली कोड यह करता है:

push ebp
mov ebp, esp
mov ecx , DWORD [ebp+8] ;address of *a to eax

EBP+8 एक मेमोरी ऑपरेंड (स्टैक पर) है जहां कॉलिंग फ़ंक्शन द्वारा a का पता रखा गया था। आपने पॉइंटर को स्टैक से a (1455843040) पर पुनः प्राप्त करना समाप्त कर दिया। आपको अलग-अलग तत्वों को प्राप्त करने के लिए पॉइंटर को और अधिक करने की आवश्यकता है। आप कोड के साथ ऐसा कर सकते हैं जैसे:

push ebp
mov ebp, esp
mov eax , DWORD [ebp+8] ; Get address of character array into EAX
mov cl, [eax]           ; Get the first byte at that address in EAX. 

सरणी में दूसरा बाइट प्राप्त करने के लिए:

mov cl, [eax+1]         ; Get the second byte at that address in EAX.

और इसी तरह।

3
Michael Petch 25 मई 2019, 17:01