2011-01-16 2 views
0
#include <stdio.h> 

#define OPT //define for assembly 

int main() 
{ 
char chr; 
for(chr = 'A' ; chr <= 'Z' ; chr++) 
{ 
    #ifdef OPT 
    __asm 
    { 
    lea eax,chr 
    push eax 
    mov eax, putchar 
    call eax 
    pop ebx 
    } 
    #endif 

    #ifndef OPT 
    putchar(chr); 
    #endif 
} 
return 0; 
} 

При использовании кода сборки все, что происходит, - это случайный символ мусора. Обратите внимание, что это синтаксис intel.C/C++ Встроенная сборка [с петлями C]

также: Я учусь ассемблерные, как бы вы захватить возвращаемое значение вызываемой функции (через MOV EAX, FUNC затем вызвать EAX или эквив?)

+0

Что не так с помощью 'call putchar'? – TonyK

+0

TonyK, вы не можете вызвать putchar, потому что putchar - это переменная. Я думаю, что это в основном для целей отладки и может быть включено или выключено в настройках компилятора C. –

+0

@ Aleš Keprt: Это новое на меня! – TonyK

ответ

4

Это не работает, потому что LEA инструкция предназначена для получения адреса переменной. (+1 к zebarbox для этой ноты.) Нам необходимо значение CHR, а не его адрес, поэтому мы используем вместо этого:

movsx eax,chr 

Это псевдоинструкции будет компилировать что-то вроде этого:

movsx eax,[ebp-4] 

Вы также можете написать putchar (chr), поставить там точку останова, запустить приложение и посмотреть в окне разборки, чтобы посмотреть, как он скомпилирован.

Обратите внимание, что я использую movsx, потому что chr является символом, и мне нужно здесь слово. Если chr был int, я просто использовал бы инструкцию mov.

Кроме того, вы не можете использовать pop ebx, так как здесь не следует изменять ebx. Использовать pop eax или Добавить esp, 4 вместо.

+0

lea используется для загрузки адреса переменной в eax и поэтому вы будете использовать ее, если функция ожидает указатель - он не имеет ничего общего со статическими или глобальными переменными. – zebrabox

+1

Я могу сделать lea на локальной переменной, если захочу, не знаете, что вы подразумеваете под постоянным адресом? т. е. \t char text [] = "Hello World"; \t _asm \t { \t \t Леа EAX, текст \t \t толчок е \t \t вызова DWORD PTR Printf \t \t поп EAX \t} – zebrabox

+0

zebrabox: Хороший вопрос! Ваш текстовый пример работает, потому что ваш lea получает адрес текстового массива, а не его значение. Исходный пример не работает с lea, потому что нам нужно значение chr, а не его адрес. Спасибо за эту заметку, я собираюсь добавить ее в свой ответ. –

1

Вот ваш правильный код:

int c = chr; 
__asm 
{ 
    mov eax, c 
    push eax 
    mov eax, putchar 
    call eax 
    pop ebx 
} 

Вы не можете двигаться chr на eax, из-за размера конфликтов. Поэтому я использовал 'c' типа int!

+0

Спасибо, это работает. – Saustin

Смежные вопросы