наверно речь о том что
(varA+1) это и будет адрес переменнойКод:varA ld hl,#xxxx
наверно речь о том что
(varA+1) это и будет адрес переменнойКод:varA ld hl,#xxxx
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
За сколько напишешь на голом ассемблере такую процедуру вывода окна с динамическим списком опций из разных массивов и выбора одной из них? И стОит ли оно столько времени? Я на Паскале за один день написал и отладил:
Код:procedure window_dialog_sub1; begin case w_items[w_dialog_i,1] of view_science_1: write(s_text[w_items[w_dialog_i,2]]); view_civ_1: write(civ_text[w_items[w_dialog_i,2]]); view_city_1: write(c_text[w_items[w_dialog_i,2]]); view_unit_1: write(u_text[w_items[w_dialog_i,2]],' ',u[w_items[w_dialog_i,2],u_at],'/', u[w_items[w_dialog_i,2],u_def],'/',u[w_items[w_dialog_i,2],u_speed]); view_building_1: write(b_text[w_items[w_dialog_i,2]]); view_tax_1: begin tax_view:=(w_items[w_dialog_i,2]-1)*10; write(tax_view,'%'); end; end; end; procedure window_clear_put; { w_dialog_center - окно по центру w_dialog_x - x левого верхнего угла окна, если w_dialog_center=0 w_dialog_y - y левого верхнего угла окна, если w_dialog_center=0 w_dialog_w - ширина окна w_dialog_h - высота окна w_dialog_color1 - цвета рамки w_dialog_color2 - цвета окна } begin if w_dialog_center=1 then begin w_dialog_x:=(32-w_dialog_w)/2; w_dialog_y:=(24-w_dialog_h)/2; end; color(w_dialog_color2); WindowSet(w_dialog_x,w_dialog_y,w_dialog_w,w_dialog_h); WindowClear; for i2:=0 to w_dialog_w-1 do begin SpritePutClear(FRAME_H,w_dialog_color1,i2+w_dialog_x,w_dialog_y); SpritePutClear(FRAME_H,w_dialog_color1,i2+w_dialog_x,w_dialog_y+w_dialog_h-1); end; for i2:=0 to w_dialog_h-1 do begin SpritePutClear(FRAME_V,w_dialog_color1,w_dialog_x,i2+w_dialog_y); SpritePutClear(FRAME_V,w_dialog_color1,w_dialog_x+w_dialog_w-1,i2+w_dialog_y); end; SpritePutClear(FRAME_LU,w_dialog_color1,w_dialog_x,w_dialog_y); SpritePutClear(FRAME_RU,w_dialog_color1,w_dialog_x+w_dialog_w-1,w_dialog_y); SpritePutClear(FRAME_LD,w_dialog_color1,w_dialog_x,w_dialog_y+w_dialog_h-1); SpritePutClear(FRAME_RD,w_dialog_color1,w_dialog_x+w_dialog_w-1,w_dialog_y+w_dialog_h-1); end; procedure window_dialog; { Параметры процедуры window_dialog: вход: w_dialog_center - окно по центру w_dialog_x - x левого верхнего угла окна, если w_dialog_center=0 w_dialog_y - y левого верхнего угла окна, если w_dialog_center=0 w_dialog_w - ширина окна w_dialog_h - высота окна w_dialog_items - количество элементов w_items[] - параметры элементов: номер таблицы, номер элемента w_dialog_text1 - заголовок 1 окна w_dialog_text2 - заголовок 2 окна w_dialog_color1 - цвета рамки w_dialog_color2 - цвета окна w_dialog_color3 - цвета окна и элементов w_dialog_color4 - цвета окна и курсора w_dialog_cancel - возможность отказа от выбора (1=да/0=нет) выход: w_dialog_case - выбранный элемент (0, если отказ от выбора) промежуточные: w_dialog_i1 - первый видимый элемент w_dialog_i2 - последний видимый элемент w_dialog_cursor - вертик.координата курсора } begin w_dialog_case:=1; w_dialog_cursor:=1; w_dialog_i1:=1; if (w_dialog_h-4)>w_dialog_items then w_dialog_i2:=w_dialog_items else w_dialog_i2:=w_dialog_h-4; window_clear_put; color(w_dialog_color2); gotoxy((w_dialog_x+1)*2,w_dialog_y+1); writeln(w_dialog_text1); gotoxy((w_dialog_x+1)*2,w_dialog_y+2); writeln(w_dialog_text2); repeat color(w_dialog_color3); WindowSet(w_dialog_x+1,w_dialog_y+3,w_dialog_w-2,w_dialog_h-4); WindowClear; for w_dialog_i:=w_dialog_i1 to w_dialog_i2 do begin gotoxy((w_dialog_x+1)*2,w_dialog_y+3+w_dialog_i-w_dialog_i1); window_dialog_sub1; end; color(w_dialog_color4); gotoxy((w_dialog_x+1)*2,w_dialog_y+2+w_dialog_cursor); for w_dialog_i:=1 to (w_dialog_w-2)*2 do write(' '); gotoxy((w_dialog_x+1)*2,w_dialog_y+2+w_dialog_cursor); w_dialog_i:=w_dialog_case; window_dialog_sub1; repeat readkey(key1,key2,key3); if key1=81 then if w_dialog_case>1 then begin w_dialog_case:=w_dialog_case-1; w_dialog_cursor:=w_dialog_cursor-1; if w_dialog_case<w_dialog_i1 then begin w_dialog_i1:=w_dialog_i1-1; w_dialog_i2:=w_dialog_i2-1; w_dialog_cursor:=w_dialog_cursor+1; end; end; if key1=65 then if w_dialog_case<w_dialog_items then begin w_dialog_case:=w_dialog_case+1; w_dialog_cursor:=w_dialog_cursor+1; if w_dialog_case>w_dialog_i2 then begin w_dialog_i1:=w_dialog_i1+1; w_dialog_i2:=w_dialog_i2+1; w_dialog_cursor:=w_dialog_cursor-1; end; end; if key1<>0 then delay(10); until key1<>0; if key1=32 and w_dialog_cancel=1 then w_dialog_case:=0; until key1=13 or w_dialog_case=0; color(0); clrscr; end;![]()
а на голом и не будут писать такое, макросы + шитый или байт-код
Прихожу без разрешения, сею смерть и разрушение...
Доброго времени суток. Снова вопрос нуба. Циклы на ассемблере организуются только через DJNZ? Ну я имею ввиду, что для организации цикла длиной более 255 итераций нужно создавать вложенные циклы? Или можно, к примеру, грузить в регистровую пару DE число итераций, затем грузить содержимое регистра D в аккумулятор и сравнивать его с регистром E. Пока сравнение ложно, флаг Z равен 0. И тогда JR NZ,nn снова запускаем выполнение блока кода? Или где-то я ошибся?
Обычно так и делают, только не сравнение, а OR - LD BC/DE/HL,NN: DEC Rx: LD A,R_high: OR R_low: JR NZ,REPEAT
Можно и без использования аккумулятора, но тогда значение нужно пересчитать вручную/средствами ассемблера, на выходе будет что-то типа
LD DE,NN
....
DEC E
JR NZ,REPEAT
DEC D
JR NZ,REPEAT
в общем, вложенный цикл, где счетчик рассчитан так, чтобы работал корректно, т.к. регистры уменьшаются независимо друг от друга
Zidane(01.08.2022)
Так ещё можно:
О, вот тебе и раз - опоздал. Ну и ладно.Код:ld de, 1000 ; будем делать 1000 итераций ld b,e ; подготовка регистров dec de ; подготовка регистров inc d ; подготовка регистров ld hl,0 ; после выполнения цикла, в hl должно быть значение 1000 Loop: inc hl djnz Loop dec d jp nz,Loop![]()
Последний раз редактировалось 0xDEAD; 01.08.2022 в 20:07.
Evgeny Muchkin(07.08.2022), Zidane(01.08.2022)
В общем решил так:
Если использовать CP C, то выполняется почему то 253 итерации. И все. А вот с OR пошло как надо. Всем спасибо )LD BC,nn ;количество итераций, 2 байта
LD HL,nn ;число с которым выполняются операции
LOOP
LD A,n ;константа в регистр
; Код программы
DEC BC
LD A,B
OR C
JR NZ,LOOP
LD A,n не имеет смысла, т.к. чуть ниже идёт LD A,B
Ну и попробуем сравнить:
или такКод:ld bc, 1000 loop: dec bc ; 6t ld a,b ; 4t or c ; 4t jr nz, loop ; 12t ; итого 26 тактов
или такКод:ld bc, 1000 loop: djnz loop ; 13/8t dec c ; 4t jr nz, loop ; 12/7t ; итого 29 тактов (чуть меньше, т.к. последний виток быстрее переход)
и предложенное вышеКод:ld bc, 1000 loop: dec c ; 4t jr nz, loop ; 12/7t dec b ; 4t jr nz, loop ; 12/7t ; итого 32 такта (чуть меньше, т.к. последний виток быстрее переход)
Код:ld de, 1000 loop: dec de ; 6t bit 7,d ; 8t jr z, loop ; 12t ; итого 26 тактов
Первый вариант быстрее, и чуть короче, но использует регистр А.
Третий вариант медленнее второго, но зато не привязан к B, можно использовать два любых регистра.
Четвёртый не привязан к А, но имеет ограничение на 32765 значений.
Что лучше - выбирать нужно по конкретной задаче.
Последний раз редактировалось Bedazzle; 02.08.2022 в 13:01.
Heavy on the disasm
Eric and the disasm
Mask 3: Venom strikes disasm
Bard's disasm
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)