Почему мы должны разыменовывать стандартный вывод здесь? - PullRequest
1 голос
/ 03 апреля 2019

Я пытаюсь вызвать fputs(str, stdout); из сборки.

Почему я должен push dword [stdout] вместо просто push stdout?

Так как в C мы не делаем fputs(str, *stdout), зачем нам разыменовывать stdout в сборке?

Полный код:

extern fputs
extern stdout

section .data
    hw: db "Hello World!", 10, 0

section .text
    global main

main:
    enter 0,0

    push dword [stdout]
    ;push stdout
    push hw
    call fputs

    leave
    mov eax, 0
    ret

1 Ответ

4 голосов
/ 03 апреля 2019

Вы разыменовываете метку asm stdout, что эквивалентно &stdout в C. Это статическое место в памяти, где хранится значение FILE* .

Только массивы типов C ведут себя как метки asm, где имя в C - это адрес, а не содержимое.

См. Также Почему в NASM мы должны использовать квадратные скобки ([]) для MOVв ячейку памяти?


В NASM пустое имя символа является статическим адресом.В C голое имя - это значение .

(За исключением истинных массивов C, где голое имя - это адрес первого элемента.)


In Cпеременные с автоматическим хранением также могут иметь имена, а не только статические.В asm символы могут идти только по статическим адресам.(Автоматическое хранение в C обычно является регистром в x86 asm или пространством стека, например [ebp - 8], если вам нужно вылить / перезагрузить. Адреса стека не являются константами времени соединения, поэтому не могут иметь метки. Вы относитесь к стеку относительнов ESP или EBP.)

Объекты с динамическим хранилищем не могут иметь имен в C, на которые могут указывать только именованные указатели.

...