Вызов функции C из кода сборки с использованием ассемблера as88 - PullRequest
3 голосов
/ 29 мая 2011

Я работаю над калькулятором с плавающей запятой для 16-битных процессоров, в частности 8086/8088.Я использую as88 Tracker , который не реализует плавающие точки, не позволяя мне использовать sscanf с "% f".

Я думал об этом в коде C и вызывал эту функциюиз моего кода ассемблера, но не мог узнать, как это сделать.

Это мой код:

 #include "../syscalnr.h"

.sect .text
_code_:     
        push    bp
        mov bp, sp

        push    SEGOP-PRIOP ! Pushes PRIOP String Size into the stack
        push    PRIOP       
        push    STDOUT      
        push    _WRITE          ! System Call to print string on the display
        sys

        add sp, 8
        mov di, rasc    ! Prepares DI to receive char
        push    _GETCHAR
1:      sys
        cmpb    al, '\n'    ! Compares with EOL and keeps storing the string chars
        je  2f
        stosb           ! Stores char into variable rasc
        jmp 1b

2:      xorb    al, al      ! Clears registers
        add sp, 2

.sect .data
_data_:

PRIOP:      .asciz  "Insert first operand:\n "
SEGOP:      .ascii  "Insert second operand: "

FORMAT:     .asciz  "%u"
F_CHAR:     .asciz  "%c"
F_STR:      .asciz  "%s\n"

.sect .bss
_bss_:          
rasc:       .space  10

Я хочу написать функцию C как:

float* getVal(char* ch) {

    float fVal;
    sscanf(ch, "%f", &fVal);

    if(fVal == 0) return 0;

    return fVal;
}

И вызвать ее из моего кода сборкичтобы перевести введенный пользователем номер строки в число с плавающей точкой.

Может кто-нибудь помочь мне с этим?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 29 мая 2011

Во-первых, это будет работать, только если ваша библиотека C работает и на эмуляторе.Я не знаю точно, насколько близко ваш эмулятор 8088 соответствует ABI x86, но, если предположить, что он не сильно изменился за последние 20 лет (кашель), вы вызываете функции C из ассемблера следующим образом:

    push    RETVAL    ;last parameter first (address of float to return)
    push    STRFLOAT  ;first parameter last (format string)
    call    sscanf    ;error code is in ax
    add     sp,4      ;returned float is at RETVAL
    ;do something...

.sect .data
    STRFLOAT: .asciz  "%f"

.sect .bss
    RETVAL:   .space 4

В зависимости от названия вы можете заменить sscanf на _sscanf или sscanf_.

0 голосов
/ 29 мая 2011

Существует соглашение о вызове функций на языке C, которое определяет, как должны быть установлены регистры при вводе функции. Вам нужно выяснить, что это за соглашение - возможно, посмотрев на скомпилированный C-файл obj, - и затем заставить свой asm-код придерживаться его так же, как вы делаете, когда выполняете sys. Я не думаю, что это будет вашей единственной проблемой, потому что sscanf (), несомненно, вызывает тонны других функций в библиотеке C, которые вам затем нужно будет найти; и понять; и интегрировать; и отладка; и так далее. Забудь этот шум.

Предупреждение о незапрошенном совете: Возможно, было бы проще - было бы проще, если бы я делал это - просто проанализировать ввод прямо в вашем коде asm. Если парень печатает «3.14159», это довольно просто, не так ли? Даже если вы видите вклад в научную нотацию, это не так уж плохо, imo.

...