Aiwan \ (•◡•) / _bot
что значит d после smart? случайно не размер ?
Aiwan \ (•◡•) / _bot
поставь b (byte) у тя же bNum размером в байт
Amber
поставь b (byte) у тя же bNum размером в байт
В любом случае не помогает
Amber
printf так же показывает
Amber
Даже с dw так
Aiwan \ (•◡•) / _bot
а с dq?
Amber
а с dq?
Так же
Aiwan \ (•◡•) / _bot
что там еще есть вместо smart?
Amber
что там еще есть вместо smart?
О, uint показывает правильно
Amber
А что с принтфом делать?
Aiwan \ (•◡•) / _bot
а что с ним?
Amber
Даже с dw так
Вот так показывает
Aiwan \ (•◡•) / _bot
ты кажись параметры неправильно передаешь
Aiwan \ (•◡•) / _bot
в rsi утя участок памяти начиная с bNum размером в 8 байт кладется
Aiwan \ (•◡•) / _bot
или там указатель?
Amber
в rsi утя участок памяти начиная с bNum размером в 8 байт кладется
Аа, всё, спасибо, извините что потратил время, потому что я передавал в rdi просто bNum, а printf'у нужен [bNum]..
Искандер
[NASM x64] global _ft_strcmp ;int strcmp(const char *s1, const char *s2); _ft_strcmp: rep cmpsb ; сравниваю rdi и rsi jne ret_ne ; если последние сравненные символы не равны - jmp xor rax, rax ; если равны - обнуляю rax, чтобы вернуть 0 ret ret_ne: jbe lower ja higher lower: mov rax, -1 ret higher: mov rax, 1 ret Ребят, подскажите пожалуйста в чем загвоздка. После выполнения rep cmpsb исполнение всегда уходит в jne. Даже в случае если строки были равные - не проскакивает. Понимаю что очень наивный код, но сижу и ломаю голову почему он не работает. Есть мысль что стоп кондишн у rep такой, что исполняя эту инструкцию вообще невозможно узнать что строки были равны... Туплю
Aiwan \ (•◡•) / _bot
а попробуй repe cmpsb
Искандер
Искандер
(output)
Aiwan \ (•◡•) / _bot
но теперь то не "всегда уходит в jne"
Искандер
Разве? Ведь не обнулился rax в третьем случае. (когда равны строки)
Искандер
Ребята в IRC говорят что мне нужно сначала длинну строки узнать и ее инициализировать в rxc(ecx?)
Искандер
Искандер
Нет) Я думал что просто rep\repe будет достаточно, т.к. он наткнется на \0 байт в одной из строк
Aiwan \ (•◡•) / _bot
в любой справке говорится что счетчик для rep это *cx. ты точно справкой пользуешься?
Искандер
Дико извиняюсь. Я просто до этого писал strlen и там без *cx имплементировал все, т.к. длина строки неизвестна априори. Буду читать справку.
Aiwan \ (•◡•) / _bot
start: stdcall cmpStr,str1,str2 .if eax cinvoke printf,szEqual cinvoke _getch .else cinvoke printf,szNot_e cinvoke _getch .endif exit: invoke ExitProcess,0 ;==================================== proc cmpStr,str1,str2 stdcall LenStr,[str1] mov ebx,eax stdcall LenStr,[str2] .if ebx = eax xor ecx,ecx mov esi,[str1] mov edi,[str2] .repeat inc ecx cmpsb .if ~ ZERO? mov eax,FALSE ret .endif .until ecx = eax mov eax,TRUE ret .else mov eax,FALSE ret .endif proc LenStr,str mov ecx,-1 mov esi,[str] .repeat inc ecx .until byte[esi+ecx] = 0 mov eax,ecx ret endp endp section '.data' data readable writable str1 db "Hello world!",0 str2 db "Hello world!",0 szNot_e db "Strings not equal",0 szEqual db "Strings equal",0
Aiwan \ (•◡•) / _bot
Aiwan \ (•◡•) / _bot
Искандер
Спасибо большое, даже как-то неудобно что так подробно все!
Aiwan \ (•◡•) / _bot
ты изобретаешь велосипед, это все есть в сети
Искандер
конвенция вызова кладет не в те регистры
Текущее состояние вот такое: global _ft_strcmp ; char *strcpy(char * dst, const char * src); _ft_strcmp: extern _ft_strlen call _ft_strlen mov rcx, rbx rep cmpsb jne ret_ne xor rax, rax ret ret_ne: jbe lower ja higher lower: mov rax, -1 ret higher: mov rax, 1 ret
Искандер
конвенция вызова кладет не в те регистры
А можно поподробнее, плз, в каком моменте это происходит? Спасибо!
Искандер
блин, я дубина... т.е. нужно в rBx ложить численное значение, а rax это exit code?
Искандер
вызываю из си
електр🟢нік ✙🟠рчбеч ඞ
нет, оно ложит параметры по порядку, но первые 2 регистра rdi и rsi только в 64-битном коде
електр🟢нік ✙🟠рчбеч ඞ
в rcx можно просто ложить -1
електр🟢нік ✙🟠рчбеч ඞ
repe вместо rep
Искандер
нет, оно ложит параметры по порядку, но первые 2 регистра rdi и rsi только в 64-битном коде
global _ft_strcmp ; char *strcpy(char * dst, const char * src); _ft_strcmp: mov rcx, -1 repe cmpsb jne ret_ne xor rax, rax ret ret_ne: jbe lower ja higher lower: mov rax, -1 ret higher: mov rax, 1 ret
Искандер
Аутпут (не работает): strcmp("abcd", "abCd") = -1 strcmp("abCd", "abcd") = 1 strcmp("abcd", "abcd") = 1 Ааааа я тупой........
Eugene
в rcx можно просто ложить -1
Я бы не стал. Если строки одинаковые, пойдет дальше, вплоть до защищенных областей нравится.
Amber
Сделал 3 файла, bar.asm, kitchen.asm и bakery.asm. По очереди каждый собираю в .о, далее делаю такую линковку gcc -o bakery bakery.o bar.o kitchen.o -no-pie main функция находится в bakery, но по непонятным мне причинам они не могут определится с bar.asm у кого функция главнее и вызываются сразу оба. Т.е. сначала идёт из main функция greeting, потом идёт функция из бара, и потом продолжается main. С kitchen такой проблемы нет. Как мне определить main как главную?
Amber
https://pastebin.com/uJMkGqs6
Aiwan \ (•◡•) / _bot
а при линковке разве нельзя определить точку входа?
Amber
а при линковке разве нельзя определить точку входа?
Попробовал это gcc -o bakery bakery.o bar.o kitchen.o -no-pie -Wl,--entry=main Теперь выдаёт segmentation fault
Amber
И всё равно этот чай проскакивает
s54820
https://pastebin.com/uJMkGqs6
Тут два файла. Где третий?
Amber
Тут два файла. Где третий?
В третем проблем нет
Amber
Проблема что после greeting откуда-то берётся make_tea
Amber
greeting там тоже нет.
https://pastebin.com/F3EaJiHH Вот все файлы
Amber
Извиняюсь, кухню перепутал
s54820
https://pastebin.com/F3EaJiHH Вот все файлы
Вот я вижу leave в greeting, а ret не вижу. Это нормально?
Amber
Вот я вижу leave в greeting, а ret не вижу. Это нормально?
Оооо, спасибо, в этом и была проблема
Искандер
Мужики, а вот такая конструкция сработает, чисто концептуально? NASM 64 extern _errno ;libc <syscall write/read> jnz error ret error: call _errno ret
Искандер
:D а конструктивно?))) это часть задания просто, используя _errno либсишный иннформацию об ошибке вывести
Eugene
Мужики, а вот такая конструкция сработает, чисто концептуально? NASM 64 extern _errno ;libc <syscall write/read> jnz error ret error: call _errno ret
Syscall — это инструкция без параметров. После её выполнения в linux возвращаются значения в регистра общего назначения, не во флагах. Если у тебя будет обертка, тогда работать будет.
Eugene
Концептуально :)
Aiwan \ (•◡•) / _bot
я както просто использовал perror, если в выполнении фукнции была ошибка, то выводилось сообщение
Aiwan \ (•◡•) / _bot
Искандер
Да, вот собсна это и задача. Спасибо, пойду играться
Искандер
Ткните пожалуйста носом, почему здесь Address boundary error? BITS 64 DEFAULT REL ; RIP-relative addressing by default ; compile with: ; nasm -g -f macho64 ft_write.s ; gcc -o a.out ft_write.o main.c ; glibc stuff extern _errno ; code section .text global _ft_write _ft_write: push rsp push rax push rbp push r8 sub rsp, 16 mov r8, 0x2000004 ; write syscall location lea rax, [r8] syscall test rax, rax jne error xor rax, rax add rsp, 16 pop rbp pop rax pop rsppop r8 ret error: add rsp, 16 call _errno pop rbp pop rax pop rsp pop r8 ret
Искандер
extern int ft_write(int fildes, const void *buf, size_t buf_size); int main(void) { ft_write(1, "test", 4); }
Искандер
Много вопросов задаю, сори. Но реально не понимаю(
Искандер
terminated by signal SIGSEGV (Address boundary error) stack_not_16_byte_aligned_error
електр🟢нік ✙🟠рчбеч ඞ
stack not 16 byte aligned
електр🟢нік ✙🟠рчбеч ඞ
push rbp mov rbp, rsp and rsp, ~(0xf)
електр🟢нік ✙🟠рчбеч ඞ
только надо придумать как сломать стек обратно перед выходом
Искандер
Я собственно и код который вы предложили не особо понимаю. А уж сломать :D
електр🟢нік ✙🟠рчбеч ඞ
попробуй скомпилить с fstack-protector
Искандер
Не помогло
Искандер
Это Сишная, из libc. =)