LINUX.ORG.RU
ФорумTalks

попытка вывести на экран массив символов

 


0

1

здрасьте здрасьте люди добрые.

как вы считаете почему не получается вот такой вот трюк:

.section .text
.global main
main:

push %rbp
mov %rsp, %rbp
subq $16, %rsp

movq $777, -16(%rsp)

mov $1, %rax
lea -16(%rsp), %rsi
mov $5, %rdx

syscall 


leave
ret

что исправить, чтобы прочитать из локальной переменной -16(%rsp) c помощью системного вызова?

ты зачем пытаешься записать данные ПОД стек? )))
все локальные переменные могут лежать только в положительных смещениях от RSP
а трюк «запись под стек» я использовал только один раз в жизни, когда писал саморасшифровывающийся «на лету» код на 8086, чтобы затруднить его прохождение по шагам в дебаггере. разумеется, прерывания были запрещены и никаких вызовов не было

Egor_
()
Последнее исправление: Egor_ (всего исправлений: 2)
Ответ на: комментарий от Assembler

нет
командой subq $16, %rsp вы зарезервировали 16 байт локальных переменных от +0(%rsp) до +15(%rsp)
то есть, буфер может начинаться с, например +0(%rsp)
буфер нужно заполнить выводимой строкой (число 777 - это два байта 9 и 3, вы на экране их не увидите)
а ещё в RDI нужно занести file descriptor

Egor_
()
Ответ на: комментарий от Miguel

да, я отстал от жизни
там же есть 128-байтовая красная зона

Egor_
()
Ответ на: комментарий от Assembler

короче, я всё неправильно написал ))

вот тут хороший пример как написать программку, которая печатает на экран число
https://stackoverflow.com/questions/45835456/printing-an-integer-as-a-string-with-att-syntax-with-linux-system-calls-instea/45851398#45851398

если внутри вашей функции вы не собираетесь вызывать другие функции, то можно использовать 128 байт ниже стека

типо, должно получиться как-то так:

main:

movq $0x636261, -16(%rsp)
mov $1, %rax
lea -16(%rsp), %rsi
mov $3, %rdx
mov $1, %edi
syscall 

ret
Egor_
()
Ответ на: комментарий от Egor_

я что пишу файловый дескриптор, что нет, все равно работает. я уже подумал что rdi необязательный параметр для sys_write .

спасибо что сказали как правильно помещать на стек локальные переменные. и бы так и толкал их в сторону роста стека.

Assembler
() автор топика
Ответ на: комментарий от Miguel

ребята, сотня извинений, но вот может вы прольете свет, зачем функция хранит свои формальные параметры на стеке? я взамешательстве.

Assembler
() автор топика
Ответ на: комментарий от Assembler

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

Assembler
() автор топика
Ответ на: комментарий от Assembler

А где, собственно? Стек ровно для этого и придуман.

Miguel ★★★★★
()
Ответ на: комментарий от Assembler

зачем функция хранит свои формальные параметры на стеке

Там и локальные переменные хранятся. Хотя и не обязательно хранить данные именно на том же стеке где хранятся переходы. Например в форте 2 отдельных стека, один для данных, другой для возвратов.

Суть в том, что параметры и переменные нужно куда-то класть и если это будет не стек, а просто область данных, то при рекурсивном вызове функции предыдущие параметры затрутся. А на стеке при каждом вызове ты получаешь новый фрейм. При выходе освобождаешь, причём не нужно следить, где что лежит, а тупо переместить указатель стека туда где был до вызова.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

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

допустим я передал в функцию число 11. вижу что будет примерно так


void foo(int a);
вот тут "a"  -есть формальный параметр.
foo(11);// тут же 11 есть фактический параметр.
понимаете? 

mov $11, %rdi// это то что я передаю в функцию
так как int  то будет что-то вроде этого

mov %rdi, -8(%rbp)// все! именно это будет на стеке, когда рекурсия к примеру.  

но я не пойму почему они твердят о формальных параметрах на стеке.

Assembler
() автор топика
Последнее исправление: Assembler (всего исправлений: 1)
Ответ на: комментарий от Assembler

почему они твердят о формальных параметрах на стеке

Потому что они имеют в виду соответствие смещения на стеке -8(%rbp) формальному параметру. Содержится там, разумеется, фактическое значение.

no-such-file ★★★★★
()
Ответ на: комментарий от Assembler

с рекурсией не совсем так.

ну такой простой пример.

foo:
push %rbp
mov %rsp, %rbp
subq $32, %rsp

mov %rdi, -8(%rbp)

cmp $0, -8(%rbp)

jne dw

mov $1, %rax//  ну это типа  return того когда должен случиться выход из рекурсии.

jmp stop

dw:
mov -8(%rbp), %rax
sub $1, %rax
mov %rax, %rdi

call foo// вот тут опр количество раз на стек будет ложится адрес из ip то есть адрес следующей инструкции.   и управления будет передаваться наверх к метке foo.  когда условие не выполнится и безусловный прыжок совершится к метке stop то ret начнет снимать со стека адреса те что туда ложила call а это были адреса из  ip регистра, то есть адреса следующих инструкций. и когда очередь ret снимет все до момента вызова foo из main то управление передастся инструкции что была ниже call  foo в main.  ну это будет add $5, %r11. вобще ненужная строчка. просто ради примера.


stop:

leave 
ret


.section .text
global main
main:

push %rbp
mov %rsp, %rbp

mov $4, %rax
call foo
add $5, %r11


leave 
ret

ничего эта функция не делат. она просто буде вызываться рекурсивно, пока -8(%rbp) не станет равно 0 и как только это случится она вернет 1.

Assembler
() автор топика
Ответ на: комментарий от no-such-file

вот спасибо вам форумчанин. кажется понял что они имели ввиду

Assembler
() автор топика
Ответ на: комментарий от Assembler

и да, самое важное

foo:


call foo



stop:
leave 
ret 



тут рекурсивном вызове на стек будет ложиться адрес метки stop: а управление будет передаваться c помощью call наверх к foo: а выполняться будет это все дело от stop: до ret . ну это тут так, потому что ничего больше ненаписанно.

Assembler
() автор топика
Последнее исправление: Assembler (всего исправлений: 1)
Ответ на: комментарий от Egor_

ребята, а подсказать то можете что исправить , чтобы прочитать из

-16(%rsp)

Assembler
() автор топика
Ответ на: комментарий от Assembler

я что пишу файловый дескриптор, что нет, все равно работает. я уже подумал что rdi необязательный параметр для sys_write .

Не думаю что файловый дескриптор не нужен.

tyamur ★★
()
Ответ на: комментарий от Assembler
        mov     r0, #255
        mov     r1,#3
        mul     r0,r0,r1
        add     r0,r0,#12 ; r0 - 777
        str     r0, [sp, #12] ; сохраняем в стек со смещением 12


        mov r7,#4 ; 4 номер системного вызова write
        mov r0,#1 ; 1 файловый дескриптор cout
        mov r1,sp 
        add r1,r1,#12 ; r1 адрес памяти sp + 12
        mov r2,#1 ; r2 кол-во байт.
        swi 0 ; syscall
tyamur ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.