- 1
Посоны, как заставить Watcom нормально адресовать? Он тупо пихает адреса, относительно нуля, а надо, что относительно сегментных регистров
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−46
Посоны, как заставить Watcom нормально адресовать? Он тупо пихает адреса, относительно нуля, а надо, что относительно сегментных регистров
guest 07.02.2017 22:17 # −5
dm_fomenok 07.02.2017 23:04 # +3
doctor_stertor 07.02.2017 23:13 # +1
Могу ли я сделать деанон, или ты предпочитаешь оставить это под завесой тайны?
guest0 07.02.2017 23:16 # −12
doctor_stertor 07.02.2017 23:55 # +1
(Надел мантию, регалии, шапочку кардинала)
козьим голосом: Готов ли ты к деано-о-о-о-ону, сын мой?
guest0 08.02.2017 00:24 # −13
huest 08.02.2017 00:07 # 0
dm_fomenok 08.02.2017 00:10 # 0
guest0 08.02.2017 18:20 # −13
я, например, тоже догадываюсь кто ты и стертор, но есть несколько вариантов
dm_fomenok 08.02.2017 21:14 # 0
guest0 08.02.2017 22:28 # −13
bormand 08.02.2017 22:36 # −13
dxd 08.02.2017 22:41 # 0
inkanus-gray 08.02.2017 11:10 # 0
dm_fomenok 08.02.2017 13:30 # 0
Долбаный линкер заменяет адрес строки на константу, а не отступ от регистра ds.
inkanus-gray 08.02.2017 14:05 # 0
declares ptr to be a pointer to an integer. The object ptr is near (addressable using only 16 bits), but the value of the pointer is the address of an integer which is far, and so the pointer contains 32 bits.
also declares fptr to be a pointer to an integer. However, the object fptr is far, but the integer that it points to is near.
declares ffptr to be a pointer (which is far) to an integer (which is far).
Это для моделей с 16-битными смещениями. Для редко используемой сегментной модели с 32-битными смещениями будет аналогично.
dm_fomenok 08.02.2017 14:36 # 0
inkanus-gray 08.02.2017 15:25 # +1
Попробовать объявить следующие переменные и посмотреть, что сгенерируется в итоге:
По идее первый пример запрещает размещать константу в другом сегменте, хотя кладёт в указатель полный адрес (сегмент + смещение). Второй пример разрешает размещать константу где угодно, но в указатель кладёт только смещение относительно сегмента. Третий пример разрешает размещать константу где угодно и в указатель кладёт полный адрес (сегмент + смещение).
inkanus-gray 08.02.2017 16:19 # 0
Итого: указатели value2 и value3 (соответственно типа char __far * и char __far * __far) хранят полный адрес (сегмент и смещение), указатель value1 хранит только смещение относительно DS.
Переменные value1 и value2 (соответственно типов char * __far и char __far * __far) лежат в отдельном сегменте (не в общем сегменте данных).
Теперь ясно, на что влияет модификатор __far до звёздочки и после звёздочки.
Итого: тип (char __near *) хранит только смещение, тип (char __far *) хранит смещение и сегмент.
dm_fomenok 08.02.2017 17:17 # 0
inkanus-gray 08.02.2017 17:35 # 0
В модели Small (16 бит) и Flat (32 бита) все указатели по умолчанию имеют тип __near.
В моделях Compact, Large и Huge указатели на данные по умолчанию __far, если явно не указано __near (т. е. в этих моделях __far для указателя на строку писать не обязательно).
В моделях Medium, Large и Huge указатели на функции по умолчанию имеют тип __far.
Huge означает почти то же самое, что и Large, но там компилятор вставляет дополнительные хаки для массивов, превышающих размер сегмента.
dm_fomenok 08.02.2017 18:23 # 0
#define fixaddr(value) (value + xxx)
ASD_77 16.03.2017 12:15 # −1
Dummy00001 08.02.2017 18:20 # 0
пример кода?
ЗЫ адреса в сегменте данных - они всегда константами были. и даже сейчас очень часто они константы. вопрос - относительно чего они константы. примерчик/демонстрация бы не помешала.
dm_fomenok 08.02.2017 18:32 # 0
#define fixaddr(value) (value + xxx). Если этого не писать то прога будет обращаться по адресу куда захотел линкер(он по факту вставляет физический)
bormand 08.02.2017 18:36 # −13
З.Ы. Или ты реально под 16 бит кодишь?
dm_fomenok 08.02.2017 18:38 # 0
dm_fomenok 08.02.2017 18:39 # 0
bormand 08.02.2017 18:43 # −13
dm_fomenok 08.02.2017 18:45 # 0
bormand 08.02.2017 18:47 # −12
Боюсь, что у тебя просто int недостаточно разработан, чтобы вместить указатель.
dm_fomenok 08.02.2017 18:53 # 0
println(i2s(sizeof(char*)));
println(i2s((int)"String"));
Выводит 4 и 2394
bormand 08.02.2017 18:55 # −10
З.Ы. В идеале - через uintptr_t. Но не факт, что он там есть...
dm_fomenok 08.02.2017 18:59 # 0
Подтверждаю, это так.
> > Тогда тебе надо через unsigned long указатели разглядывать, а не через int.
Я их вообще не разглядываю. Я тупо передаю char* в println. Если предварительно не пофиксить через fixaddr литерал, то он указывает не куда то там, А НА АДРЕС С ДАННЫМИ В БИНАРНИКЕ. Из за этого нужно прибавлять констунту, равну адресу точки входа в приложение (_cstart)
bormand 08.02.2017 19:03 # −13
bormand 08.02.2017 19:05 # −12
inkanus-gray 08.02.2017 19:05 # 0
bormand 08.02.2017 19:10 # −13
dm_fomenok 08.02.2017 19:16 # +2
Режим реальный, 16 бит, всё по харду.
Вся эта поебень стоит в MBR.
jmp kernel
db 495 dup(0)
db 55h, 0AAh
db 0
kernel:
mov sp,07C00h
А теперь даю код print:
void print(char* value)
{
int i = 0;
while (value[i]) putch(value[i++]);
}
println тоже самое, только с выводом перевода строки
bormand 08.02.2017 19:17 # −12
Ч.т.д. Предчувствия меня не обманули.
dm_fomenok 08.02.2017 19:23 # 0
bormand 08.02.2017 19:23 # −13
dm_fomenok 08.02.2017 19:26 # 0
bormand 08.02.2017 19:39 # −12
Кто бы знал, что это значит с точки зрения ватнокома...
Если просто линковка под конкретный адрес - должна быть какая-то опция, которой этот адрес задаётся. Плюс ты должен поместить образ в правильное место в памяти и правильно настроить как минимум cs и ds. Как - х.з., я ватноком ни разу не юзал.
inkanus-gray 08.02.2017 19:40 # 0
dm_fomenok 08.02.2017 19:42 # +3
Есть ещё вторая опция -- offset, через него я пытался фиксить адреса, но линкер не даёт мне 7C00h, он округляет до 8000h
bormand 08.02.2017 19:44 # −12
Значит так и надо. Не спорь с ним. Забей лишнее место нулями, к примеру. Или на асме подвинь/прочитай образ куда надо.
Остаётся узнать, что надо положить в cs и ds чтобы всё заработало...
dm_fomenok 08.02.2017 19:46 # 0
bormand 08.02.2017 19:48 # −12
dm_fomenok 08.02.2017 19:51 # 0
bormand 08.02.2017 19:53 # −13
dm_fomenok 08.02.2017 20:05 # 0
00000229: 8CD2 mov dx, ss
0000022B: B8F284 mov ax, 84F2
0000022E: 89C3 mov bx, ax
00000230: 89D8 mov ax, bx
00000232: 0E push cs
00000233: E87205 call 000007A8
Вызов вывода строки с адресом 84F2 -- адрес после прибавления к нему 7C00 макросом.
bormand 08.02.2017 20:15 # −13
Кстати, а ты ds куда настраиваешь в стартовом коде на асме? И настраиваешь ли вообще?
> push cs
> call
Лол, байты экономят что ли? :) Чтобы функция думала, что её вызвали как far?
inkanus-gray 08.02.2017 20:16 # +2
P.S. Это не только экономия байтов, но и экономия на фиксапах. Если сделать call near, то адрес будет относительный и фиксап делать не нужно, если функция в том же сегменте. А в стеке будет такое же смещение, как и при call far.
inkanus-gray 08.02.2017 20:31 # +2
1. В байтовом представлении инструкций JMP SHORT (включая условные переходы), JMP NEAR, CALL NEAR хардкодится смещение не относительно сегмента, а относительно конца данной инструкции. Т. е. опкод JMP SHORT/NEAR, за которым следует ноль, эквивалентен бесполезной инструкции NOP. Адреса коротких переходов патчить не нужно.
2. В байтовом представлении JMP FAR, CALL FAR хардкодится смещение относительно сегмента. В экзешнике после загрузки придётся патчить адреса, если он загружен по адресу, отличающемуся от дефолтного.
3. И после вызова CALL NEAR, и после вызова CALL FAR в стеке будет смещение относительно сегмента, хотя в байтовом представлении CALL NEAR хардкодится относительный адрес.
4. Для инструкций, работающих с данными, (типа MOV) аналога с относительными адресами нет. Адреса данных всегда хардкодятся от начала сегмента. Если экзешник загружен по адресу, отличающемуся от дефолтного, их нужно патчить.
barop 08.02.2017 20:59 # −13
именно потому большинство линкёров в современных ОС умеют PIC. Там в заголовке даны адреса для "подвигать'
inkanus-gray 08.02.2017 21:40 # 0
А без PIC вместе с экзешником нужно хранить таблицу релокейшнов (фиксапов), которую загрузчик при старте экзешника должен пробегать и патчить по ней образ свежезагруженного экзешника.
bormand 08.02.2017 21:02 # −12
barop 08.02.2017 21:03 # −13
inkanus-gray 08.02.2017 21:34 # 0
In the legacy x86 architecture, addressing relative to the instruction pointer is available only in controltransfer instructions. In the 64-bit mode, any instruction that uses ModRM addressing can use RIPrelative addressing. This feature is particularly useful for addressing data in position-independent code and for code that addresses global data.
Without RIP-relative addressing, ModRM instructions address memory relative to zero. With RIPrelative addressing, ModRM instructions can address memory relative to the 64-bit RIP using a signed 32-bit displacement. This provides an offset range of ±2 Gbytes from the RIP.
Programs usually have many references to data, especially global data, that are not register-based. To load such a program, the loader typically selects a location for the program in memory and then adjusts program references to global data based on the load location. RIP-relative addressing of data makes this adjustment unnecessary.
inkanus-gray 08.02.2017 20:04 # +2
bormand 08.02.2017 19:51 # −11
Блять, ну вот как мы тебе должны советовать, если не видим ни образа, ни исходников... Это ж ёбаная нейрохирургия по скайпу.
inkanus-gray 08.02.2017 19:47 # 0
Dummy00001 08.02.2017 20:08 # 0
так это же стандартное встроенное счастье!
ядро так можно (и часто нужно) компилить. но динамически загружаемые модуля - нет.
вообщем, фоменОку надо начинать учить форматы exe-шников и учиться писать загрузчик оных. а потом просто проги компилить в тот формат, и их грузить для исполнения.
inkanus-gray 08.02.2017 20:09 # 0
guestinho 16.03.2017 22:20 # −13
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
guestinho 16.03.2017 22:21 # −13
guestinho 16.03.2017 22:13 # −13
guestinho 16.03.2017 22:14 # −13
guestinho 16.03.2017 22:19 # −13
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
guestinho 16.03.2017 22:20 # −13
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
Vanished
guestinho 16.03.2017 22:21 # −13
Dr_Stertor 16.03.2017 22:30 # −13
Dummy00001 08.02.2017 20:02 # 0
линкер, да, та инстанция которая говорит какие аддреса будут. компилятор это та инстанция которая говорит какими *типами* адресов код будет пользоватся.
вообщем, тебе не хватает нечто типа `ASSUME DS:DSEG`.
Dr_Stertor 16.03.2017 22:34 # −13
bormand 08.02.2017 19:14 # −11
Но надо больше инфы - операционку, формат бинаря и т.п.
inkanus-gray 08.02.2017 19:24 # 0
Ну ещё как вариант навелосипедить аналог PIC.
bormand 08.02.2017 19:26 # −13
inkanus-gray 08.02.2017 19:33 # +2
Нужно только научиться пользоваться его линкером.
bormand 08.02.2017 19:56 # −12
bormand 08.02.2017 20:25 # −13
inkanus-gray 08.02.2017 21:22 # 0
bormand 08.02.2017 21:42 # −12
j123123 09.02.2017 10:33 # +2
кроме того, ваткомовый ассемблер умеет делать elf файлы, которые потом скорее всего вполне сожрутся гнутым линкером
inkanus-gray 09.02.2017 12:21 # 0
j123123 09.02.2017 12:23 # +3
Dr_Stertor 16.03.2017 22:34 # −13
Dummy00001 08.02.2017 19:58 # 0
bormand 08.02.2017 20:02 # −12
dm_fomenok 08.02.2017 21:46 # +3
Хуй там. У меня весь код в одном сишном файле, компилится в один бинарник на 3 КБ. И главное, что работает, если не считать то, что вручную надо фиксить адресацию.
> > Читал бы "ядро" на 0x8000.
Не царское это дело читать ядро, это дело для bios. (А с хуя ли он кстати загружает весь бинарь?)
inkanus-gray 08.02.2017 21:53 # 0
bormand 08.02.2017 21:57 # −13
inkanus-gray 08.02.2017 22:06 # 0
dm_fomenok 08.02.2017 22:08 # 0
bormand 08.02.2017 22:10 # −13
dm_fomenok 08.02.2017 22:11 # 0
bormand 08.02.2017 22:13 # −13
inkanus-gray 08.02.2017 22:12 # +2
В принципе, можем написать собственный менеджер загрузки?
inkanus-gray 08.02.2017 22:11 # 0
Загрузчики, отличные от стандартных Windows-загрузчиков, могут использовать всё пространство между MBR и первым разделом (около 32 кБ; 1-й–63-й сектора́) для собственных целей. В таких случаях под MBR понимают весь загрузочный код, а для выделения именно первых 512 байт говорят, что они расположены в MBS (Master Boot Sector) — главном загрузочном секторе.
Похоже, что BIOS окончанием MBR считает не окончание первого сектора, а сектор, в конце которого встретилась сигнатура 0x55, 0xAA.
bormand 08.02.2017 22:15 # −11
ek_fomenok 09.02.2017 02:53 # 0
guest0 08.02.2017 18:26 # −13
А што это за хуйня такая, просвети
bormand 08.02.2017 18:35 # −13
Для flat модели памяти это нормально.
dm_fomenok 08.02.2017 18:36 # 0
guest0 08.02.2017 18:50 # −13
bormand 08.02.2017 18:51 # −12
inkanus-gray 08.02.2017 19:00 # +2
http://www.netlore.ru/fisting-ataka
dm_fomenok 08.02.2017 20:16 # +3
bormand 08.02.2017 20:23 # −9
guest0 08.02.2017 22:25 # −12
j123123 09.02.2017 03:36 # 0
bormand 09.02.2017 07:13 # −13
1024-- 09.02.2017 12:33 # 0
> Поспорил на штукарь, что напишу на сишке аналог DOS.
guest0 09.02.2017 18:42 # −11