[{"isEmailConfirmed":true,"tel":"","ip":"0.0.0.0","ipLocation":{"ip":"","sDate":3,"postalCode":"","country":"","countryIsoCode":"","federalDistrict":"","region":"","regionType":"","city":"","cityType":"","geoLat":"","geoLon":"","locationString":""},"birthDate":"0001-01-01T00:00:00","age":0,"isBirthdayToday":false,"ban":{"id":0,"userId":0,"isBanned":false,"startDate":"0001-01-01T00:00:00","endDate":"0001-01-01T00:00:00","moder":{"id":0,"name":"Неизвестный","email":"нет адреса","role":0,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isValid":false,"isLoggedIn":false,"isUnconfirmed":true,"isConfirmed":false,"isNewUser":false,"isExisted":false,"isExpert":false,"isRfproUserClass":false},"reasonHTML":"","timeToUnbanString":"-54 мин."},"isBanned":false,"roleString":"Мастер-Эксперт","roleIcon":"fa-user-ninja","socialMedia":[],"aboutText":"","aboutHTML":"","signatureText":"Facta loquuntur.","signatureHTML":"Facta loquuntur.","country":{"id":0,"name":"","isFlagExists":false,"flagImage":"","isValid":false},"city":{"id":0,"name":"","countryId":0,"yandexCityId":0,"isValid":false},"averageEvaluation":4.979,"absoluteRating":109944,"dynamicRating":1660.277,"dynamicRatingStars":10,"timezone":{"id":0,"baseUtcOffset":"00:00:00","displayName":"[не установлен]","linuxid":"notset/clean"},"currentDateTime":"2024-07-04T09:54:56.0452106+03:00","isValid":true,"isUnconfirmed":false,"isConfirmed":true,"settings":{"fixedHeader":true,"fixedFooter":true,"leftColumnMode":2,"darkTheme":false,"topPanelBtns":[{"id":103,"text":"Главная","title":"Главная (начальная) страница Портала","icon":"fa-solid fa-house-chimney","colorClass":"text-info-emphasis","controller":"Home","action":"Index","accessLevel":0,"isDropdown":false},{"id":100,"text":"Вход в систему","title":"Войти в систему с использованием своих регистрационных данных (адрес электронной почты и пароль)","icon":"fa-solid fa-arrow-right-to-bracket","colorClass":"text-info-emphasis","controller":"Login","action":"Index","accessLevel":0,"isDropdown":false},{"id":101,"text":"Регистрация","title":"Зарегистрироваться в системе и стать полноценным участником сообщества","icon":"fa-solid fa-user-plus","colorClass":"text-info-emphasis","controller":"Regist","action":"Index","accessLevel":0,"isDropdown":false},{"id":102,"text":"Сброс пароля","title":"Сбросить пароль свой учетной записи, если Вы его забыли","icon":"fa-solid fa-key","colorClass":"text-danger-emphasis","controller":"Login","action":"ResetPassword","accessLevel":0,"isDropdown":false}],"topPanelBtnsHideText":false},"isLevelUpAllowed":false,"nextRole":11,"counters":{"daysAtPortal":6622,"questions":12,"questionsPosts":18353,"questionsAnswers":6665,"questionsPostsEvaluations":2833,"forumPosts":5699},"isRfproUserClass":true,"id":17387,"name":"Гордиенко Андрей Владимирович","email":"","role":10,"registDate":"1000-01-01T00:00:00","lastDate":"2024-07-02T17:20:02","photo":"users/17387/f4979bc95a484b9f43f75cfe66538acd.jpg","lastDateIndicatorClass":"red","lastDateIndicatorText":"давно","photoPreview200":"users/17387/200_f4979bc95a484b9f43f75cfe66538acd.jpg","photoPreview120":"users/17387/120_f4979bc95a484b9f43f75cfe66538acd.jpg","photoPreview100":"users/17387/100_f4979bc95a484b9f43f75cfe66538acd.jpg","photoPreview80":"users/17387/80_f4979bc95a484b9f43f75cfe66538acd.jpg","photoPreview40":"users/17387/40_f4979bc95a484b9f43f75cfe66538acd.jpg","isPhotoExists":true,"isLoggedIn":true,"isNewUser":false,"isExisted":true,"isExpert":true},{"isEmailConfirmed":true,"tel":"","ip":"0.0.0.0","ipLocation":{"ip":"","sDate":3,"postalCode":"","country":"","countryIsoCode":"","federalDistrict":"","region":"","regionType":"","city":"","cityType":"","geoLat":"","geoLon":"","locationString":""},"birthDate":"0001-01-01T00:00:00","age":0,"isBirthdayToday":false,"ban":{"id":0,"userId":0,"isBanned":false,"startDate":"0001-01-01T00:00:00","endDate":"0001-01-01T00:00:00","moder":{"id":0,"name":"Неизвестный","email":"нет адреса","role":0,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isValid":false,"isLoggedIn":false,"isUnconfirmed":true,"isConfirmed":false,"isNewUser":false,"isExisted":false,"isExpert":false,"isRfproUserClass":false},"reasonHTML":"","timeToUnbanString":"-54 мин."},"isBanned":false,"roleString":"Мастер-Эксперт","roleIcon":"fa-user-ninja","socialMedia":[],"aboutText":"Я пенсионер. Образование высш, радио-инж. Работал инж-электроником, ведущим средств телевидения, связи, слесарем и инженером КИП, грузчиком, программистом. На моём счету десятки рац-предложений, в тч с большим экономич эффектом.\nЯ люблю компьютеры, ремонтирую их друзьям и соседям. Пишу полезные программки в vbs-файлах, автоматизирующие настройку Win-систем, приложений и работу с ними.","aboutHTML":"Я пенсионер. Образование высш, радио-инж. Работал инж-электроником, ведущим средств телевидения, связи, слесарем и инженером КИП, грузчиком, программистом. На моём счету десятки рац-предложений, в тч с большим экономич эффектом.\u003Cbr\u003EЯ люблю компьютеры, ремонтирую их друзьям и соседям. Пишу полезные программки в vbs-файлах, автоматизирующие настройку Win-систем, приложений и работу с ними.","signatureText":"","signatureHTML":"","country":{"id":0,"name":"","isFlagExists":false,"flagImage":"","isValid":false},"city":{"id":0,"name":"","countryId":0,"yandexCityId":0,"isValid":false},"averageEvaluation":4.935,"absoluteRating":25767,"dynamicRating":455.695,"dynamicRatingStars":8,"timezone":{"id":0,"baseUtcOffset":"00:00:00","displayName":"[не установлен]","linuxid":"notset/clean"},"currentDateTime":"2024-07-04T09:54:56.0455494+03:00","isValid":true,"isUnconfirmed":false,"isConfirmed":true,"settings":{"fixedHeader":true,"fixedFooter":true,"leftColumnMode":2,"darkTheme":false,"topPanelBtns":[{"id":103,"text":"Главная","title":"Главная (начальная) страница Портала","icon":"fa-solid fa-house-chimney","colorClass":"text-info-emphasis","controller":"Home","action":"Index","accessLevel":0,"isDropdown":false},{"id":100,"text":"Вход в систему","title":"Войти в систему с использованием своих регистрационных данных (адрес электронной почты и пароль)","icon":"fa-solid fa-arrow-right-to-bracket","colorClass":"text-info-emphasis","controller":"Login","action":"Index","accessLevel":0,"isDropdown":false},{"id":101,"text":"Регистрация","title":"Зарегистрироваться в системе и стать полноценным участником сообщества","icon":"fa-solid fa-user-plus","colorClass":"text-info-emphasis","controller":"Regist","action":"Index","accessLevel":0,"isDropdown":false},{"id":102,"text":"Сброс пароля","title":"Сбросить пароль свой учетной записи, если Вы его забыли","icon":"fa-solid fa-key","colorClass":"text-danger-emphasis","controller":"Login","action":"ResetPassword","accessLevel":0,"isDropdown":false}],"topPanelBtnsHideText":false},"isLevelUpAllowed":false,"nextRole":11,"counters":{"daysAtPortal":5654,"questions":25,"questionsPosts":7464,"questionsAnswers":1226,"questionsPostsEvaluations":789,"forumPosts":401},"isRfproUserClass":true,"id":259041,"name":"Алексеев Владимир Николаевич","email":"","role":10,"registDate":"1000-01-01T00:00:00","lastDate":"2024-07-01T01:22:07","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"red","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isLoggedIn":true,"isNewUser":false,"isExisted":true,"isExpert":true},{"isEmailConfirmed":true,"tel":"","ip":"0.0.0.0","ipLocation":{"ip":"","sDate":3,"postalCode":"","country":"","countryIsoCode":"","federalDistrict":"","region":"","regionType":"","city":"","cityType":"","geoLat":"","geoLon":"","locationString":""},"birthDate":"0001-01-01T00:00:00","age":0,"isBirthdayToday":false,"ban":{"id":0,"userId":0,"isBanned":false,"startDate":"0001-01-01T00:00:00","endDate":"0001-01-01T00:00:00","moder":{"id":0,"name":"Неизвестный","email":"нет адреса","role":0,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isValid":false,"isLoggedIn":false,"isUnconfirmed":true,"isConfirmed":false,"isNewUser":false,"isExisted":false,"isExpert":false,"isRfproUserClass":false},"reasonHTML":"","timeToUnbanString":"-54 мин."},"isBanned":false,"roleString":"Старший Модератор","roleIcon":"fa-user-tie","socialMedia":[],"aboutText":"634034, г.Томск, ул.Красноармейская 122, кв.173","aboutHTML":"634034, г.Томск, ул.Красноармейская 122, кв.173","signatureText":"","signatureHTML":"","country":{"id":0,"name":"","isFlagExists":false,"flagImage":"","isValid":false},"city":{"id":0,"name":"","countryId":0,"yandexCityId":0,"isValid":false},"averageEvaluation":4.985,"absoluteRating":21746,"dynamicRating":407.309,"dynamicRatingStars":8,"timezone":{"id":0,"baseUtcOffset":"00:00:00","displayName":"[не установлен]","linuxid":"notset/clean"},"currentDateTime":"2024-07-04T09:54:56.0457209+03:00","isValid":true,"isUnconfirmed":false,"isConfirmed":true,"settings":{"fixedHeader":true,"fixedFooter":true,"leftColumnMode":2,"darkTheme":false,"topPanelBtns":[{"id":103,"text":"Главная","title":"Главная (начальная) страница Портала","icon":"fa-solid fa-house-chimney","colorClass":"text-info-emphasis","controller":"Home","action":"Index","accessLevel":0,"isDropdown":false},{"id":100,"text":"Вход в систему","title":"Войти в систему с использованием своих регистрационных данных (адрес электронной почты и пароль)","icon":"fa-solid fa-arrow-right-to-bracket","colorClass":"text-info-emphasis","controller":"Login","action":"Index","accessLevel":0,"isDropdown":false},{"id":101,"text":"Регистрация","title":"Зарегистрироваться в системе и стать полноценным участником сообщества","icon":"fa-solid fa-user-plus","colorClass":"text-info-emphasis","controller":"Regist","action":"Index","accessLevel":0,"isDropdown":false},{"id":102,"text":"Сброс пароля","title":"Сбросить пароль свой учетной записи, если Вы его забыли","icon":"fa-solid fa-key","colorClass":"text-danger-emphasis","controller":"Login","action":"ResetPassword","accessLevel":0,"isDropdown":false}],"topPanelBtnsHideText":false},"isLevelUpAllowed":false,"nextRole":13,"counters":{"daysAtPortal":5339,"questions":1,"questionsPosts":1973,"questionsAnswers":1283,"questionsPostsEvaluations":588,"forumPosts":91},"isRfproUserClass":true,"id":312929,"name":"Коцюрбенко Алексей Владимирович","email":"","role":12,"registDate":"1000-01-01T00:00:00","lastDate":"2024-06-01T11:08:00","photo":"users/312929/bf7398e83a2a9b679ee601a457e91a12.jpg","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"users/312929/200_bf7398e83a2a9b679ee601a457e91a12.jpg","photoPreview120":"users/312929/120_bf7398e83a2a9b679ee601a457e91a12.jpg","photoPreview100":"users/312929/100_bf7398e83a2a9b679ee601a457e91a12.jpg","photoPreview80":"users/312929/80_bf7398e83a2a9b679ee601a457e91a12.jpg","photoPreview40":"users/312929/40_bf7398e83a2a9b679ee601a457e91a12.jpg","isPhotoExists":true,"isLoggedIn":true,"isNewUser":false,"isExisted":true,"isExpert":true},{"isEmailConfirmed":true,"tel":"","ip":"0.0.0.0","ipLocation":{"ip":"","sDate":3,"postalCode":"","country":"","countryIsoCode":"","federalDistrict":"","region":"","regionType":"","city":"","cityType":"","geoLat":"","geoLon":"","locationString":""},"birthDate":"0001-01-01T00:00:00","age":0,"isBirthdayToday":false,"ban":{"id":0,"userId":0,"isBanned":false,"startDate":"0001-01-01T00:00:00","endDate":"0001-01-01T00:00:00","moder":{"id":0,"name":"Неизвестный","email":"нет адреса","role":0,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isValid":false,"isLoggedIn":false,"isUnconfirmed":true,"isConfirmed":false,"isNewUser":false,"isExisted":false,"isExpert":false,"isRfproUserClass":false},"reasonHTML":"","timeToUnbanString":"-54 мин."},"isBanned":false,"roleString":"Советник","roleIcon":"fa-user-ninja","socialMedia":[],"aboutText":"","aboutHTML":"","signatureText":"","signatureHTML":"","country":{"id":0,"name":"","isFlagExists":false,"flagImage":"","isValid":false},"city":{"id":0,"name":"","countryId":0,"yandexCityId":0,"isValid":false},"averageEvaluation":5,"absoluteRating":9460,"dynamicRating":376.59,"dynamicRatingStars":7,"timezone":{"id":0,"baseUtcOffset":"00:00:00","displayName":"[не установлен]","linuxid":"notset/clean"},"currentDateTime":"2024-07-04T09:54:56.0458583+03:00","isValid":true,"isUnconfirmed":false,"isConfirmed":true,"settings":{"fixedHeader":true,"fixedFooter":true,"leftColumnMode":2,"darkTheme":false,"topPanelBtns":[{"id":103,"text":"Главная","title":"Главная (начальная) страница Портала","icon":"fa-solid fa-house-chimney","colorClass":"text-info-emphasis","controller":"Home","action":"Index","accessLevel":0,"isDropdown":false},{"id":100,"text":"Вход в систему","title":"Войти в систему с использованием своих регистрационных данных (адрес электронной почты и пароль)","icon":"fa-solid fa-arrow-right-to-bracket","colorClass":"text-info-emphasis","controller":"Login","action":"Index","accessLevel":0,"isDropdown":false},{"id":101,"text":"Регистрация","title":"Зарегистрироваться в системе и стать полноценным участником сообщества","icon":"fa-solid fa-user-plus","colorClass":"text-info-emphasis","controller":"Regist","action":"Index","accessLevel":0,"isDropdown":false},{"id":102,"text":"Сброс пароля","title":"Сбросить пароль свой учетной записи, если Вы его забыли","icon":"fa-solid fa-key","colorClass":"text-danger-emphasis","controller":"Login","action":"ResetPassword","accessLevel":0,"isDropdown":false}],"topPanelBtnsHideText":false},"isLevelUpAllowed":false,"nextRole":10,"counters":{"daysAtPortal":2512,"questions":0,"questionsPosts":472,"questionsAnswers":398,"questionsPostsEvaluations":298,"forumPosts":1},"isRfproUserClass":true,"id":401284,"name":"Михаил Александров","email":"","role":9,"registDate":"1000-01-01T00:00:00","lastDate":"2024-06-08T19:40:08","photo":"users/401284/48171011af39b6bb3a74df8c0fcf97d0.jpg","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"users/401284/200_48171011af39b6bb3a74df8c0fcf97d0.jpg","photoPreview120":"users/401284/120_48171011af39b6bb3a74df8c0fcf97d0.jpg","photoPreview100":"users/401284/100_48171011af39b6bb3a74df8c0fcf97d0.jpg","photoPreview80":"users/401284/80_48171011af39b6bb3a74df8c0fcf97d0.jpg","photoPreview40":"users/401284/40_48171011af39b6bb3a74df8c0fcf97d0.jpg","isPhotoExists":true,"isLoggedIn":true,"isNewUser":false,"isExisted":true,"isExpert":true},{"isEmailConfirmed":true,"tel":"","ip":"0.0.0.0","ipLocation":{"ip":"","sDate":3,"postalCode":"","country":"","countryIsoCode":"","federalDistrict":"","region":"","regionType":"","city":"","cityType":"","geoLat":"","geoLon":"","locationString":""},"birthDate":"0001-01-01T00:00:00","age":0,"isBirthdayToday":false,"ban":{"id":0,"userId":0,"isBanned":false,"startDate":"0001-01-01T00:00:00","endDate":"0001-01-01T00:00:00","moder":{"id":0,"name":"Неизвестный","email":"нет адреса","role":0,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isValid":false,"isLoggedIn":false,"isUnconfirmed":true,"isConfirmed":false,"isNewUser":false,"isExisted":false,"isExpert":false,"isRfproUserClass":false},"reasonHTML":"","timeToUnbanString":"-54 мин."},"isBanned":false,"roleString":"Посетитель","roleIcon":"fa-user","socialMedia":[],"aboutText":"","aboutHTML":"","signatureText":"","signatureHTML":"","country":{"id":0,"name":"","isFlagExists":false,"flagImage":"","isValid":false},"city":{"id":0,"name":"","countryId":0,"yandexCityId":0,"isValid":false},"averageEvaluation":4.987,"absoluteRating":6052,"dynamicRating":216.881,"dynamicRatingStars":7,"timezone":{"id":0,"baseUtcOffset":"00:00:00","displayName":"[не установлен]","linuxid":"notset/clean"},"currentDateTime":"2024-07-04T09:54:56.0459761+03:00","isValid":true,"isUnconfirmed":false,"isConfirmed":true,"settings":{"fixedHeader":true,"fixedFooter":true,"leftColumnMode":2,"darkTheme":false,"topPanelBtns":[{"id":103,"text":"Главная","title":"Главная (начальная) страница Портала","icon":"fa-solid fa-house-chimney","colorClass":"text-info-emphasis","controller":"Home","action":"Index","accessLevel":0,"isDropdown":false},{"id":100,"text":"Вход в систему","title":"Войти в систему с использованием своих регистрационных данных (адрес электронной почты и пароль)","icon":"fa-solid fa-arrow-right-to-bracket","colorClass":"text-info-emphasis","controller":"Login","action":"Index","accessLevel":0,"isDropdown":false},{"id":101,"text":"Регистрация","title":"Зарегистрироваться в системе и стать полноценным участником сообщества","icon":"fa-solid fa-user-plus","colorClass":"text-info-emphasis","controller":"Regist","action":"Index","accessLevel":0,"isDropdown":false},{"id":102,"text":"Сброс пароля","title":"Сбросить пароль свой учетной записи, если Вы его забыли","icon":"fa-solid fa-key","colorClass":"text-danger-emphasis","controller":"Login","action":"ResetPassword","accessLevel":0,"isDropdown":false}],"topPanelBtnsHideText":false},"isLevelUpAllowed":false,"nextRole":2,"counters":{"daysAtPortal":2790,"questions":0,"questionsPosts":527,"questionsAnswers":250,"questionsPostsEvaluations":155,"forumPosts":0},"isRfproUserClass":true,"id":400669,"name":"epimkin","email":"","role":1,"registDate":"1000-01-01T00:00:00","lastDate":"2024-06-23T20:01:53","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isLoggedIn":true,"isNewUser":false,"isExisted":true,"isExpert":false},{"isEmailConfirmed":true,"tel":"","ip":"0.0.0.0","ipLocation":{"ip":"","sDate":3,"postalCode":"","country":"","countryIsoCode":"","federalDistrict":"","region":"","regionType":"","city":"","cityType":"","geoLat":"","geoLon":"","locationString":""},"birthDate":"0001-01-01T00:00:00","age":0,"isBirthdayToday":false,"ban":{"id":0,"userId":0,"isBanned":false,"startDate":"0001-01-01T00:00:00","endDate":"0001-01-01T00:00:00","moder":{"id":0,"name":"Неизвестный","email":"нет адреса","role":0,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isValid":false,"isLoggedIn":false,"isUnconfirmed":true,"isConfirmed":false,"isNewUser":false,"isExisted":false,"isExpert":false,"isRfproUserClass":false},"reasonHTML":"","timeToUnbanString":"-54 мин."},"isBanned":false,"roleString":"Мастер-Эксперт","roleIcon":"fa-user-ninja","socialMedia":[],"aboutText":"","aboutHTML":"","signatureText":"[i]С уважением[/i]\n[i]shvetski[/i]","signatureHTML":"\u003Ci\u003EС уважением\u003C/i\u003E\u003Cbr\u003E\u003Ci\u003Eshvetski\u003C/i\u003E","country":{"id":0,"name":"","isFlagExists":false,"flagImage":"","isValid":false},"city":{"id":0,"name":"","countryId":0,"yandexCityId":0,"isValid":false},"averageEvaluation":4.963,"absoluteRating":11493,"dynamicRating":198.812,"dynamicRatingStars":7,"timezone":{"id":0,"baseUtcOffset":"00:00:00","displayName":"[не установлен]","linuxid":"notset/clean"},"currentDateTime":"2024-07-04T09:54:56.0461236+03:00","isValid":true,"isUnconfirmed":false,"isConfirmed":true,"settings":{"fixedHeader":true,"fixedFooter":true,"leftColumnMode":2,"darkTheme":false,"topPanelBtns":[{"id":103,"text":"Главная","title":"Главная (начальная) страница Портала","icon":"fa-solid fa-house-chimney","colorClass":"text-info-emphasis","controller":"Home","action":"Index","accessLevel":0,"isDropdown":false},{"id":100,"text":"Вход в систему","title":"Войти в систему с использованием своих регистрационных данных (адрес электронной почты и пароль)","icon":"fa-solid fa-arrow-right-to-bracket","colorClass":"text-info-emphasis","controller":"Login","action":"Index","accessLevel":0,"isDropdown":false},{"id":101,"text":"Регистрация","title":"Зарегистрироваться в системе и стать полноценным участником сообщества","icon":"fa-solid fa-user-plus","colorClass":"text-info-emphasis","controller":"Regist","action":"Index","accessLevel":0,"isDropdown":false},{"id":102,"text":"Сброс пароля","title":"Сбросить пароль свой учетной записи, если Вы его забыли","icon":"fa-solid fa-key","colorClass":"text-danger-emphasis","controller":"Login","action":"ResetPassword","accessLevel":0,"isDropdown":false}],"topPanelBtnsHideText":false},"isLevelUpAllowed":false,"nextRole":11,"counters":{"daysAtPortal":5780,"questions":35,"questionsPosts":1567,"questionsAnswers":588,"questionsPostsEvaluations":324,"forumPosts":44},"isRfproUserClass":true,"id":226425,"name":"Shvetski","email":"","role":10,"registDate":"1000-01-01T00:00:00","lastDate":"2024-06-14T22:58:37","photo":"users/226425/f345a2332af0cff5fba81b60c4e0d441.jpg","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"users/226425/200_f345a2332af0cff5fba81b60c4e0d441.jpg","photoPreview120":"users/226425/120_f345a2332af0cff5fba81b60c4e0d441.jpg","photoPreview100":"users/226425/100_f345a2332af0cff5fba81b60c4e0d441.jpg","photoPreview80":"users/226425/80_f345a2332af0cff5fba81b60c4e0d441.jpg","photoPreview40":"users/226425/40_f345a2332af0cff5fba81b60c4e0d441.jpg","isPhotoExists":true,"isLoggedIn":true,"isNewUser":false,"isExisted":true,"isExpert":true}]
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: реализовать функцию 6 прерывания int 30h. В приложении модуль на Pascal (используются ассемблерные вставки). Там функция 6 реализована, однако, преподаватель сказал что реализована она "коряво", прошу Вас предложить вариант получше. Искренне благодарю за помощь!
Приложение: {---Модуль содержит константы, типы переменных, переменные,---} {------процедуры и функции для работы в защищенном режиме-----} unit prot; {12-11-09} interface const
aa:longint=$123; hex_tabl:array[0..15] of char='0123456789ABCDEF'; scan:byte=0; { Значение скан-кода нажатой клавиши } modeVA:byte=0; { Цветное изображение экрана } { =1: черно-белое } first:byte=1; { Первая запись в массив screen } save_on:byte=0; { Признак перезаписи массива в файл } {=============Селекторы дескрипторов таблицы GDT==============}
esp0,ss0, { кольца 0 } esp1,ss1, { кольца 1 } esp2,ss2, { кольца 2 } {------------------Регистры микропроцессора-------------------}
cr3,eip,eflags,eax,ecx,edx,ebx,esp,ebp,esi,edi, es,cs,ss,ds,fs,gs,ldt:longint; bit_t, { Бит ловушки задачи } adr_BKVV:word; { Смещение поля БКВВ } sys_inf:string; { Поле для системной информации } { BK_VM86:array[0..31] of byte;} BKVV:array[0..31] of byte; { БКВВ } byte_end:byte; { Байт завершения TSS } end; {=======Структура TSS для задачи виртуального режима VM86=====}
esp0,ss0, { кольца 0 } esp1,ss1, { кольца 1 } esp2,ss2, { кольца 2 } {------------------Регистры микропроцессора-------------------}
cr3,eip,eflags,eax,ecx,edx,ebx,esp,ebp,esi,edi, es,cs,ss,ds,fs,gs,ldtr:longint; bit_t, { Бит ловушки задачи } adr_BKVV:word; { Смещение БКВВ } {-----Битовая карта перенаправления программных прерываний----} BK_VM86:array[0..31] of byte; {--------------Битовая карта ввода-вывода (БКВВ)--------------} BKVV:array[0..1023*8] of byte; byte_end:byte; { Байт завершения TSS } end; var www:byte; main_tss, { Сегменты состояния задач MAIN и } exc12_tss: t_tss; { EXC12_TASK } exc12_stack:array[0..255] of byte; { стек задачи exc12 } screen: { Массив для сохранения значений } array[0..3999] of word; { двух экранов видеопамяти } offs_ekr:word; di_,cx_:word; { Переменные для хранения значений } dh_,dl_:byte; { регистров DI, CX, DH та DL } gdt:array[0..22] of t_dt; { Таблица GDT } idt:array[0..255] of t_idt; { Таблица IDT } gdtr, { Содержимое GDTR } idtr, { Содержимое IDTR для работы в защищенном режиме } idtr_r { и для работы в реальном режиме } :t_dtr; s:string; eip_:longint; ofs_end_prot, { Смещение и селектор меток } sel_end_prot, { end_prot } ofs_ret_real, sel_ret_real:word; { и ret_real } {----------Переменные для хранения значений регистров---------} {---------------------реального режима:-----------------------}
real_cs, { CS, } real_ds, { DS, } real_ss, { SS, } real_es, { ES и } real_sp:word; { SP } subf, { Номер подфункции } mode, { Режим работы МП: 0/1 (реальный/защищенный) } left_shift:byte; { Состояние клавиши Left Shift: } { 0/1 (отпущена/нажата) } {==========Объявление функций и процедур модуля PROT===========}
implementation const s_err:string='Runtime error: исключение '; s_e:string='error: '; s_reg:array[0..7] of string= (' EAX ',' ECX ',' EDX ',' EBX ', ' ESP ',' EBP ',' ESI ',' EDI '); s_sreg:array[0..6] of string=(' EIP ',' CS ',' SS ' ,' ES ',' DS ',' FS ',' GS '); s_CR0:array[0..1] of string= ('PCN A W NETEMP', 'GDW резерв M P резерв ETSMPE'); s_CR0n:string='CR0:'; s_CR4n:string='CR4:'; s_CR4:array[0..2] of string= ( ' PPMPP TPV', ' Зарезервировано CGCASDSVM', ' EEEEEEDIE'); s_EFLAGSn:string='EFLAGS:'; s_EFLAGS:array[0..2] of string= (' VV ', ' IIIAVR NIPODITSZ A P C', ' резерв DPFCMF0TOLFFFFFF0F0F1F'); var i:byte; j:word;
{===========Описание функций и процедур модуля PROT===========}
{-------------Преобразование данных в 16-ричную форму---------} function hex(p:longint):string; var s:string; begin s:=''; {'h';} repeat s:=hex_tabl[p and $f]+s; p:=p shr 4 until p=0; hex:=s end;{hex} {-----Ожидание нажатия клавиши (в scan - скан-код нажатия)----} procedure wait_;assembler; asm mov scan,0 @w: cmp scan,0 jz @w test scan,80h jnz @w { db 66h} { iret} end; procedure get_time;assembler; asm nop mov ax,100h { mov bx,2F09h {2F0Bh} {2103h} int 30h { Установка маркера в точку экрана (33,3) } mov cx,3 { Три цикла определения и вывода времени } mov al,4 { в формате чч:мм:сс } @2:push cx push ax out 70h,al in al,71h { В AL - значение часов/минут/секунд } mov cl,1dh { Видео-атрибут } mov dl,al sub di,2 mov ax,300h int 30h { Вывод на экран значения часов/минут/секунд } pop ax pop cx cmp cx,1 { В третьем цикле не надо выводить ":" } jz @1 push cx push ax mov ah,2 sub di,2 mov cl,1dh mov dl,3ah int 30h { Вывод на экран символа ":" } pop ax sub al,2 pop cx loop @2 @1: db 66h { Использовался 32-разрядный вызов процедуры; } { команды RETF нет, так как она подставляется транслятором } end; {------------Формирование дескриптора таблицы GDT-------------} procedure init_gdt(sel:word;limit,base:longint;acc_, byte_6:byte); begin with gdt[sel shr 3] do begin if limit>$FFFFF then begin limit:=limit shr 12; byte_6:=byte_6 or $80; end; lim_l :=limit; base_l :=base; base_h :=base shr 16; acc :=acc_; lim_h :=limit shr 16 or byte_6; base_hh:=base shr 24; end end; {init_dt} {------Формирование данных регистра GDTR и его загрузка-------} procedure init_gdtr(sel:word); begin gdtr.lim:=sel+7; gdtr.base:=longint(seg(gdt)) shl 4+ofs(gdt); asm db 0fh,01h,16h { LGDT gdtr: } dw gdtr { загрузка атрибутов GDT в GDTR из gdtr } end end; {init_gdtr} {------------Формирование дескриптора таблицы IDT-------------} procedure init_idt(i:byte;ofs_:longint;sel_:word;acc_:byte); begin with idt[i] do begin ofs_l:=ofs_; sel:=sel_; par:=0; acc:=acc_; ofs_h:=ofs_ shr 16; end end; {init_idt} {-----------Запрет внешних аппаратных прерываний,-------------} {-----сохрание содержимого регистра IDTR реального режима,----} {-------формирование данных регистра IDTR и его загрузка------} {---------------для работы в защищенном режиме----------------} procedure init_idtr; begin asm cli { Запрет маскируемых и } mov al,80h { немаскируемых } out 70h,al { прерываний } db 0fh,1,0eh { SIDT idtr_r: } dw idtr_r { Сохранение атрибутов IDT в idtr_r } end; idtr.lim:=sizeof(idt)-1; idtr.base:=longint(seg(idt)) shl 4+ofs(idt); asm db 0fh,01h,1eh { LIDT idtr: } dw idtr { Загрузка атрибутов IDT в IDTR из idtr } end; end;{init_idtr} {------------Программирование ведущего и ведомого-------------} {--------------контроллеров прерываний для работы-------------} {------в реальном (mode=0) и защищенном (mode=1) режимах------} procedure pic(mode:byte); var k1,k2:byte; begin if mode=0 then begin k1:=8; k2:=$70 end else begin k1:=$20; k2:=$28 end; port[$20]:=$11; { 1-й ПКП: ICW1 } port[$21]:=k1; { 1-й ПКП: ICW2 } port[$21]:=4; { 1-й ПКП: ICW3 } port[$21]:=1; { 1-й ПКП: ICW4 } port[$a0]:=$11; { 2-й ПКП: ICW1 } port[$a1]:=k2; { 2-й ПКП: ICW2 } port[$a1]:=2; { 2-й ПКП: ICW3 } port[$a1]:=1; { 2-й ПКП: ICW4 } end;{pic} {------------Формирование TSS для 32-разрядных МП-------------} procedure init_tss(var tss:t_tss; cs,ds,es,ip,sp:word); begin tss.cs:=cs; tss.ds:=ds; tss.es:=es; tss.ss:=ds; tss.eip:=ip; tss.esp:=sp; tss.eflags:=$200; tss.bit_t:=0; tss.byte_end:=$ff end;{init_tss}
{---------------Для работы в режиме "Unreal"------------------} {---для заданного сегментного регистра указываются параметры--} {--связанного с ним сегмента памяти, которые могут отличаться-} {----от параметров реального режима: граница сегмента и его---} {----базовый адрес могут быть увеличены до величины 4 ГБ-1----} procedure set_unr(s_reg:byte;limit,base:longint;byte_6:byte); begin {------------------Формирование таблицы GDT-------------------}
@k:db 0fh,20h,0c0h { MOV EAX,CR0 } and al,not 1 db 0fh,22h,0c0h { MOV CR0,EAX } {--------------------Разрешение прерываний-------------------} sti { маскируемых } mov al,0Dh out 70h,al { и немаскируемых } end; end;{set_unr}
{---------Сохранение изображения экрана в массиве screen-------} procedure save_ekran;assembler; asm cmp scan,0E0h { Если два первых скан-кода клавиши } mov scan,al jnz @3 { являються кодами E0h и 2Ah, т.е. } cmp al,2Ah { нажата клавиша "Print Screen", то } jnz @3 mov save_on,1 { установить признак сохранения екрана } cmp first,1 jz @1 add offs_ekr,2400 { Изменить смещение массива и } mov ax,700h { сохранить помощью функции 7 INT 30h } mov bx,0 { текущее содержимое области экрана } mov dx,4F18h { с координатами: (0,0) и (79,24), } int 30h { т.е. весь экран в массиве screen } jmp @end @1: mov first,0 @2: jmp @end @3: cmp al,0E0h { Если скан-код нажатой клавиши равен E0h } jnz @end cmp first,1 { и сброшен признак сохранения экрана - } jnz @end mov ax,700h { с помощью функции 7 INT 30h сохранить } mov bx,0 { текущее содержимое области экрана } mov dx,4F18h int 30h cmp save_on,0 { Признак сохранения екрана установлен? } jnz @1 { Если нет - } mov save_on,1 { установить признак сохранения екрана } add offs_ekr,2400 { и изменить смещение массива } jmp @end { для сохранения 2-го экрана, } (* @1: { если да - } mov ax,700h { с помощью функции 7 INT 30h сохранить } mov bx,0 { текущее содержимое области экрана } mov dx,4F18h { с координатами: (0,0) и (79,24), } int 30h { т.е. весь экран в массиве screen } jmp @end
@2: cmp al,0E0h { Если скан-код нажатой клавиши равен E0h } jnz @end cmp save_on,0 { и сброшен признак сохранения экрана - } jnz @end mov ax,700h { с помощью функции 7 INT 30h сохранить } mov bx,0 { текущее содержимое области экрана } mov dx,4F18h int 30h *) @end: end;{save_ekran}
{-----Сохранение значения массива ekran на магнитном диске----} procedure save_scr; const s_arr:string='Введите имя массива для сохранения экрана'; var save_scr_:string; ekr:file of word; k:integer; begin if boolean(save_on) then begin { asm mov ax,0b800h mov es,ax mov ax,102h mov cl,70h mov bx,16h int 30h end; } writeln('Введите имя массива для сохранения экрана'); readln(save_scr_); if save_scr_<>'' then begin save_scr_:='EKRAN/'+save_scr_; assign(ekr,save_scr_); rewrite(ekr); for k:=0 to 3999 do write(ekr,screen[k]); end; end; end;
{----------Обработчики исключений 0-8, 10-14, 16-18-----------} {---(процедуры exc_00-exc_08, exc_10-exc_14, exc_116-exc_18)--} {-------выводят на экран номер исключения, адрес команды------} {--------------и завершают выполнение программы---------------}
procedure exc_00;assembler; { Обработчик исключения 0: } asm { деление на 0 } mov ah,1 { Функция 1 прерывания 32h: } mov dx,100h { вывод на экран номера исключения (0) } int 32h { и адреса команды } db 0ffh,2eh { Межсегментный переход } dw ofs_end_prot { на метку end_prot: } end; procedure exc_01;assembler; { Обработчик исключения 1: } asm { - при TF=1 регистра EFLAGS; } mov ah,1 { - при T=1 сегмента TSS; } mov dx,101h { - по контрольным точкам программы; } int 32h { - по контрольным точкам данных; } db 0ffh,2eh { - по контрольным точкам УВВ; } dw ofs_end_prot { - при защите регистров отладки } end; procedure exc_02;assembler; { Обработчик исключения 2: } asm { немаскируемое прерывание (NMI) } mov ah,1 mov dx,102h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_03;assembler; { Обработчик исключения 3: } asm { по команде INT 3 } mov ah,1 mov dx,103h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_04;assembler; { Обработчик исключения 4: } asm { по команде INTO при OF=1 } mov ah,1 mov dx,104h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_05;assembler; { Обработчик исключения 5: } asm { выход за пределы диапазона } mov ah,1 { при выполнении команды BOUND } mov dx,105h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_06;assembler; { Обработчик исключения 6: } asm { неверный код операции } mov ah,1 { или адресации } mov dx,106h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_07;assembler; { Обработчик исключения 7: } asm { недоступно устройство FPU } mov ah,1 mov dx,107h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_08;assembler; { Обработчик исключения 8: } asm { двойная ошибка } mov ah,1 mov dx,108h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_10;assembler; { Обработчик исключения 10: } asm { недоступен TSS } mov ah,1 mov dx,10Ah int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_11;assembler; { Обработчик исключения 11: } asm { недоступен сегмент } mov ah,1 mov dx,10Bh int 32h db 0ffh,2eh dw ofs_end_prot end; {--Задача EXC12_TASK: обработчик исключения 12: ошибка стека--} procedure exc12_task;assembler; asm @12: mov ah,1 mov dx,0Ch int 32h mov scan,0 @w:cmp scan,0 { Задержка до нажатия любой клавиши } jz @w test scan,80h jnz @w {----------Анализ бита P дескриптора сегмента стека:----------} {----------------если сброшен - восстановить------------------}
mov bx,offset main_tss mov bx,[bx+80] { Из TSS читается селектор стека } test byte ptr [offset gdt+bx+5],80h jnz @1 or byte ptr [offset gdt+bx+5],80h jmp @end {------Если бит P не сброшен - изменить указатель стека-------} @1: mov bx,offset main_tss mov ax,0fffh { Значение 0FFFh } mov [bx+56],ax { заносится в поле ESP сегмента TSS } {--------------и завершить выполнение программы---------------}
mov ax,ofs_end_prot { Смещение метки end_prot } mov [bx+32],ax { заносится в поле EIP сегмента TSS } @end: db 66h iret jmp @12 end;{exc12_task} procedure exc_13;assembler; { Обработчик исключения 13: } asm { нарушение общей защиты } {---Анализ вызова обработчика прерывания 13 для определения,--} {--------это исключение 13 или возврат из режима VM8086-------} push ax push ds mov ax,30h mov ds,ax mov bp,sp mov ax, [bp+12] cmp ax,real_cs { Если селектор CS в стеке является } pop ds { базовым адресом реального режима - } pop ax jnz @err db 0eah { тогда: переключение на задачу MAIN } dw 0 { для выхода из режима VM8086, } dw main_sel @err: mov ah,1 { иначе: вывод на экран сообщения о том, } mov dx,10Dh { что возникло исключение 13 } int 32h db 0ffh,2eh { и завершение программы } dw ofs_end_prot end; procedure exc_14;assembler; { Обработчик исключения 14: } asm { недоступна страница } mov ah,1 mov dx,10Eh int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_16;assembler; { Обработчик исключения 16: } asm { ошибка FPU при NE=1 регистра CR0 } mov ah,1 mov dx,110h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_17;assembler; { Обработчик исключения 17: } asm { ошибка выравнивания данных } mov ah,1 mov dx,111h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure exc_18;assembler; { Обработчик исключения 18: } asm { ошибка функционирования узлов МП и МПС } mov ah,1 mov dx,112h int 32h db 0ffh,2eh dw ofs_end_prot end; procedure keyb;assembler; { Обработчик прерываний } asm { от клавиатуры: } pusha mov al,20h out 20h,al in al,60h { Чтение скан-кода нажатия/отжатия клавиши } cmp modeVA,1 jz @save mov scan,al jmp @scan {---------С помощью процедуры save_ekran определяется,--------} {-------------нажата ли клавиша "Print screen":---------------} {--если да - сохранить изображение экрана в переменной screen-}
@scan: cmp scan,2Ah { Нажата клавиша "левый Shift"? } jnz @k1 { Если да - } mov left_shift,1 { установить признак нажатия клавиши } jmp @end @k1: cmp scan,0AAh { Отжата клавиша "левый Shift"? } jnz @k2 { Если да - } mov left_shift,0 { сбросить признак нажатия клавиши } jmp @end @k2: cmp left_shift,1 { Если нажаты клавиши "левый Shift" } jnz @end cmp scan,0C5h { и "Pause/Break", тогда выполняется } jnz @end db 0ffh,2eh { межсегментный переход на метку end_prot } dw ofs_end_prot { для срочного завершения программы } @end:popa db 66h iret end;{keyb} {---------Обработчики-заглушки аппаратных прерываний,---------} {----------поступающих на 1-й контроллер прерываний-----------}
procedure PIC_1;assembler; asm push ax mov al,20h out 20h,al { Сброс бита регистра ISR 1-го ПКП } pop ax db 66h iret end; {---------Обработчики-заглушки аппаратных прерываний,---------} {----------поступающих на 2-й контроллер прерываний-----------}
procedure PIC_2;assembler; asm push ax mov al,20h { Сброс бита регистра ISR } out 20h,al { 1-го и } out 0a0h,al { и 2-го контроллеров прерываний } pop ax db 66h iret end; {-----------Обработчик программного прерывания 30h------------} {------выполняет вывод данных на экран в текстовом режиме-----} {------------Переменная modeVA задает режим вывода:-----------} {-------modeVA=0: цвет символов и их фона задается------------} {---------------как видеоатрибут в регистре CL;---------------} {-------modeVA=1: символы черного цвета на белом фоне,--------} {-----------------общий фон экрана - серый--------------------}
procedure int_30h;assembler; { Назначение регистров:} { AH - номер функции } { Al - номер подфункции } { BL - номер строки экрана } { BH - номер столбца экрана } { DL/DX/EDX - значение данных } { (байта/слова/двойного слова) } { CL - видеоатрибут символов } { SI - смещение строки символов } asm { DI - смещение ячейки видеопамяти }
cmp ah,0 jz @f0 cmp ah,1 jz @f1 cmp ah,2 jz @f2 cmp ah,3 jz @f3 cmp ah,4 jz @f4 cmp ah,5 jz @f5 cmp ah,6 jz @f6 cmp ah,7 jz @f7 cmp ah,8 jz @f8 jmp @end {-----Функция 0: установка назначения бита 7 видеоатрибута----} {----------------(с сохранением всех регистров)---------------} { AL=0 - режим мерцания символа } @f0: { AL=1 - режим 16-битного фона } { cmp modeVA,0 jnz @end } push ax push dx mov ah,al mov dx,3DAh in al,dx { Разрешить запись адреса (индекса) регистра } mov al,10h mov dx,3c0h { Записать адрес (10h) } out dx,al { регистра управления режимом } cmp ah,0 jnz @01 mov al,8 { режим с мерщанием символа } jmp @02 @01: mov al,0 { режим 16-цветного фона } @02: mov dx,3c0h out dx,al { Задать указанный режим } mov al,20h mov dx,3c0h out dx,al { Разрешить вывод на экран } pop dx pop ax jmp @end {-----Функция 1: установка маркера в заданную точку экрана----} {-----------(с сохранением всех регистров, кроме DI)----------} { AL=0 - без изменения экрана } { AL=1 - с очисткой до конца строки } { AL=2 - с очисткой до конца экрана } { (в CL - цвет фона экрана) } @f1: { AL=3 - c подсветкой маркера } push ax push cx push dx push bx push si mov subf,al { Сохранение номера подфункции } {------------------Установка маркера на экране----------------} mov al,bl mov dl,80 mul dl shr bx,8 add ax,bx mov dx,ax { В DX - номер места маркера } shl ax,1 mov di,ax mov si,ax { В DI,SI - адрес маркера } cmp subf,0 jz @pop cmp subf,3 jz @3 {-----------Определение числа стираемых символов--------------} mov ax,dx mov dh,0 mov dl,80 sub dl,bl { В DL - число стираемых символов в строке } cmp subf,1 jz @clear cmp subf,2 jnz @pop mov dx,ax mov ax,2000 sub ax,dx mov dx,ax { В DX - число стираемых символов на экране } {---------------------Очистка экрана--------------------------} @clear: mov al,20h { ASCII-код пробела } cmp modeVA,0 jz @12 mov ah,70h { Серый фон } jmp @121 @12: mov ah,cl { Фон задается регистром CL } @121: mov cx,dx @wxy_: stosw loop @wxy_ mov di,si jmp @pop {-----------------Установка подсветки маркера-----------------} @3: mov dx,3d4h mov al,0fh out dx,al mov dx,3d5h mov al,bl out dx,al mov dx,3d4h mov al,0eh out dx,al mov dx,3d5h mov al,bh out dx,al @pop: pop si pop bx pop dx pop cx pop ax jmp @end {---------------Функция 2: вывод символа на экран-------------} @f2: mov al,dl cmp modeVA,0 jz @21 mov ah,0f0h jmp @22 @21: mov ah,cl @22: stosw add di,2 jmp @end {------Функция 3: вывод данных на экран в 16-ричной форме-----} { AL=0 - вывод байта } { AL=1 - вывод слова } @f3: { AL=2 - вывод двойного слова } lea bx,hex_tabl cmp modeVA,0 jz @31 mov ah,0f0h jmp @32 @31: mov ah,cl @32: cmp al,0 jz @8 cmp al,1 jz @16 add di,14 mov cx,8 jmp @1 @8:add di,2 mov cx,2 jmp @1 @16:add di,6 mov cx,4 @1:push cx @lp:mov al,dl and al,0fh db 66h shr dx,4 xlat stosw sub di,4 loop @lp pop cx shl cx,1 add cx,4 {2} add di,cx jmp @end {----------Функция 4: вывод строки символов на экран----------} @f4: cmp modeVA,0 jz @41 mov ah,0f0h jmp @42 @41: mov ah,cl @42: mov bx,si inc si mov cl,[bx] cmp cl,0 jz @end xor ch,ch @wxy: lodsb stosw loop @wxy jmp @end {-------Функция 5: вывод данных на экран в двоичной форме-----} { AL=0 - вывод байта } { AL=1 - вывод слова } @f5: { AL=2 - вывод двойного слова } lea bx,hex_tabl cmp modeVA,0 jz @51 mov ah,0f0h jmp @52 @51: mov ah,cl @52: cmp al,0 jz @8_2 cmp al,1 jz @16_2 mov cx,8 jmp @2 @8_2: mov cx,2 jmp @2 @16_2: mov cx,4 @2:push cx push cx shl cx,3 sub cx,2 add di,cx { di+cx*8-2 } pop cx @lp_1:push cx xor ah,8 mov cx,4 @lp_2:mov al,dl and al,01h db 66h shr dx,1 xlat stosw sub di,4 loop @lp_2 pop cx loop @lp_1 pop cx shl cx,3 add cx,2 { di+cx*8+2 } add di,cx jmp @end {-----Функция 6: вывод данных на экран в десятичной форме-----} { AL=0 - вывод байта } { AL=1 - вывод слова } @f6: { AL=2 - вывод двойного слова } push bp push cx mov bp, sp db 66h mov cx, 0CA00h { Заносим 1 000 000 000 } dw 3B9Ah { в ECX } lea bx, hex_tabl cmp al,1 jne @6_1 db 66h and dx, 0FFFFh dw 0000h db 66h mov cx, 2710h { Заносим 10 000 } dw 0000h { в ECX } @6_1: cmp al,0 jne @6_b db 66h and dx, 000FFh dw 0000h db 66h mov cx, 0064h { Заносим 100 } dw 0000h { в ECX } jmp @6_b @osn: dw 0Ah dw 0h @6_b: {add di,2} db 66h mov ax, dx @procsym: db 66h xor dx, dx db 66h div cx mov ah, [ss:bp] xlat stosw db 66h mov ax,cx db 66h mov cx,dx db 66h xor dx, dx db 66h div word [@osn] db 66h xchg ax, cx cmp cx, 0 jne @procsym db 66h mov dx,bx pop cx pop bp jmp @end {-----Функция 7: Работа с прямоугольной областью экрана,------} {----------------ограниченной координатами:-------------------} {--------(X1,Y1) - левый верхний угол области экрана;---------} {--------(X2,Y2) - правый нижний угол области экрана----------} @f7: { AL=0: сохранить в памяти } push ax { AL=1: восстановить на экране } push bx { BX - (X1,Y1) } push dx { DX - (X2,Y2) } mov al,bl mov dl,80 mul dl shr bx,8 add ax,bx shl ax,1 mov di,ax { В DI - адрес левого верхнего угла области } mov si,di xor cx,cx pop dx pop bx pop ax sub dh,bh { X2-X1 } inc dh mov dh_,dh sub dl,bl { Y2-Y1 } inc dl mov dl_,dl mov cl,dl mov cx_,cx mov bx,offset screen add bx,offs_ekr @l2: push cx xor cx,cx mov cl,dh @l1: push cx cmp al,0 push ax jz @sto mov ax,[bx] mov es:[di],ax jmp @m @sto: mov ax,es:[di] mov [bx],ax @m: pop ax add di,2 add bx,2 pop cx loop @l1 add si,160 mov di,si pop cx loop @l2 jmp @end {---Функция 8: вывод строки из массива символов на экран-----} @f8: mov ah,cl inc si mov cx,dx @wxy8: lodsb stosw loop @wxy8 jmp @end @end:iret end; {-----------Обработчик программного прерывания 31h------------} {----------Вывод данных на экран в графическом режиме---------}
procedure int_31h;assembler; {--------------Функция 1: вывод на экран пиксела--------------} { BX - номер столбца (x) } { CX - номер строки (y) } { EDX - 32-разрядный цвет пикселя (0RGB) } asm mov ax,640 { Число пикселей в строке } db 66h and bx,0FFFFh dw 0 db 66h push dx mul cx { Произведение - в DX:AX } db 66h shl dx,16 mov dx,ax { Произведение - в EDX } db 66h add dx,bx db 66h shl dx,2 db 66h mov di,dx { В DI - адрес пикселя в видеопамяти } db 66h pop dx { db 66h} { mov dx,0FF00h dw 0h } db 66h,67h,26h,89h,17h { MOV ES:[EDI],EDX } db 66h iret end;
{------------Обработчик программного прерывания 32h-----------} {-------Вывод на экран служебной и отладочной информации------}
procedure int_32h;assembler; { Назначение регистров: } { AH - номер функции } { BH/BL - номер столбца/строки экрана } { Для функции 1 координаты курсора заданы по умолчанию: } { BL=17, BH=1 } asm {------Задание в переменной mode режима работы процессора-----} db 66h push ax db 0fh,20h,0c0h { MOV EAX,CR0 } test al,1 { Анализ режима работы МП: } jnz @pm mov mode,0 { реальный режим } jmp @beg @pm:mov mode,1 { защищенный режим } @beg: { mov mode,0} db 66h pop ax cmp ah,1 jnz @mark {----Задание для функции 1 координат маркера по умолчанию:----} mov bl,9 {17 { строка 17, } mov bh,1 { столбец 1 } push dx push dx @mark:pusha mov ax,101h { Установка маркера в точку экрана с } mov cl,0 int 30h { координатами, заданными в BH/BL } mov bp,sp { с очисткой строки } mov [bp],di popa cmp ah,1 jz @f1 cmp ah,2 jz @f2 cmp ah,3 jz @f3 cmp ah,4 jz @f4 cmp ah,5 jz @f5 cmp ah,6 jz @f6 cmp ah,7 jz @f7 jmp @end
{-------------------------Функция 1:--------------------------} {----Вывод на экран сообщения "Runtime error: исключение",----} {---номера исключения и (при необходимости) адреса команды,---} {---при выполнении которой (при отказе) или после выполнения--} {------------которой (при ловушке) возникло исключение--------} @f1: { Назначение регистров:} { DL - номер исключения } { DH - 1/0: с выводом/ } { без вывода адреса команды } mov ah,4 { Функция 4: } mov si, offset s_err mov cl,1bh int 30h { вывод на экран строки s_err } mov ax,300h { Функция 3, подфункция 0: } mov cl,1ch pop dx int 30h { вывод на экран номера исключения } pop dx mov bp,sp {------------Анализ номера возникшего исключения:-------------} {--если он равен одному из номеров 0,1,2,3,4,5,6,7,16 или 18,-} {----------то код ошибки в стек не заносился и поэтому--------} {---------------очистки стека делать не нужно-----------------} cmp dl,0 jz @3 cmp dl,1 jz @3 cmp dl,2 jz @3 cmp dl,3 jz @3 cmp dl,4 jz @3 cmp dl,5 jz @3 cmp dl,6 jz @3 cmp dl,7 jz @3 cmp dl,16 jz @3 cmp dl,18 jz @3 {-----------------Очистка стека от кода ошибки----------------} db 66h mov ax,[bp+8] db 66h mov [bp+12],ax db 66h mov ax,[bp+4] db 66h mov [bp+8],ax db 66h mov ax,[bp] db 66h mov [bp+4],ax add sp,4 mov bp,sp
{----Если при обработке возникшего исключения нужен анализ----} {------кода ошибки, то вместо вызова прерывания INT 32h-------} {-----необходимо использовать собственные средства анализа,---} {----например, как это сделано в обработчике исключения 11----} {-----------------программы P_INT (раздел 5)------------------} @3:
cmp dh,0 jz @end
{------Вывод на экран адреса (селектор:смещение) команды,-----} {-----------------которая вызвала исключение------------------}
mov ah,2 mov cl,1bh mov dl,28h int 30h { Вывод на экран символа "(" } sub di,2 mov ax,301h mov cl,1eh db 66h mov dx,[bp+16] { Чтение из стека CS } int 30h { Вывод на экран значения CS } sub di,2 mov ah,2 mov cl,1eh mov dl,3ah int 30h { Вывод на экран символа ":" } sub di,2 mov ax,302h mov cl,1eh db 66h mov dx,[bp+12] { Чтение из стека EIP } int 30h { Вывод на экран значения EIP } sub di,2 mov ah,2 mov cl,1bh mov dl,29h int 30h { Вывод на экран символа ")" } jmp @end
{------------------------Функция 2:----------------------------} {----------------Вывод на экран значений РОН:------------------} {------------EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI------------} { } {-----Особенность этой функции: перед ее вызовом необходимо----} {---------сохранить в стеке значения регистров AX и BX,--------} {-----------а после вызова функции - их восстановить-----------} {------------(см. обработчик ислючения 0 модуля PROT)----------} { В AL - режим вывода значений регистров } { AL=0: вывод в одну строку } @f2: { AL=1: вывод в две строки } {--------Сохранить параметры вызова прерывания INT 32h:-------} push ax { режим вывода и } push bx { координаты вывода } mov bp,sp cmp mode,0 {-------Восстановить исходные значения регистров AX и BX------} {---------для реального и защищенного режимов работы МП-------} jnz @pm1 mov ax,[bp+12] mov bx,[bp+10] jmp @@1 @pm1:mov ax,[bp+18] mov bx,[bp+16] @@1: db 66h pusha { Сохранить РОНы для вывода на экран } mov bp,sp mov bx,[bp+32] { Восстановить координаты места экрана } mov ax,100h int 30h { Установить маркер } {------Вывод массива строк наименований регистров (s_reg)-----} lea bx,s_reg mov cx,8 @as:push cx push bx mov ah,4 mov cl,1ah mov si,bx int 30h add di,2 pop bx add bx,256 pop cx cmp cx,5 jnz @l mov ax,[bp+34] { Анализ режима вывода: } cmp al,0 { AL=0: в одну строку } jz @l add di,408 { AL=0: в две строки } @l:loop @as mov ax,[bp+34] cmp al,0 { Анализ режима вывода } jnz @l3 add di,142 jmp @l4 @l3:add di,142 @l4:mov cx,8 @l1: db 66h pop dx { Чтение из стека значения очередного РОНа } push cx push di mov cl,1bh mov ax,302h int 30h { Вывод на экран значения очередного РОНа } pop di sub di,18 pop cx cmp cx,5 jnz @l2 mov bp,sp mov ax,[bp+18] cmp al,0 { Анализ режима вывода } jz @l2 sub di,408 @l2:loop @l1 pop bx pop ax jmp @end {--------------------------Функция 3:-------------------------} {----------Вывод на экран значений счетчика команд EIP--------} {--------и сегментных регистров CS, SS, ES, DS, FS и GS-------} { Назначение регистров: AL - номер подфункции } {------AL=0: вывод значений собственно регистров EIP и CS-----} {------AL=1: вывод "теневых" значений регистров EIP и CS------} {----В случае AL=1 перед вызовом функции необходимо задать:---} { в CX - значение CS } @f3: cmp al,0 jz @01 push cx cmp mode,0 jz @31 db 66h @31:push dx @01: push ax {-----------------Вывод массива строк s_sreg------------------} lea bx,s_sreg mov cx,7 { add di,160} @as1:push cx push bx mov ah,4 mov cl,1ah mov si,bx int 30h add di,2 pop bx add bx,256 pop cx loop @as1 add di,82 pop ax cmp al,0 jnz @02 mov bp,sp cmp mode,0 jz @32 db 66h @32:mov dx,[bp] { mov cur_adr,dx} mov cl,1bh mov ax,302h int 30h { Вывод на экран значения EIP } cmp mode,0 jnz @pm2 mov dx,[bp+2] jmp @33 @pm2:mov dx,[bp+4] { mov cur_sel,dx} @33:mov cl,1bh mov ax,301h int 30h { Вывод на экран значения CS } jmp @ss @02:cmp mode,0 jz @34 db 66h @34:pop dx mov cl,1bh mov ax,302h int 30h { Вывод на экран "теневого" значения EIP } pop dx mov cl,1bh mov ax,301h int 30h { Вывод на экран "теневого" значения CS } @ss: mov dx,ss mov cl,1bh mov ax,301h int 30h { Вывод на экран значения SS } mov dx,es mov cl,1bh mov ax,301h int 30h { Вывод на экран значения ES } mov bp,sp mov dx,ds mov cl,1bh mov ax,301h int 30h { Вывод на экран значения DS } db 8ch,0e2h { MOV DX,FS } mov cl,1bh mov ax,301h int 30h { Вывод на экран значения FS } db 8ch,0eah { MOV DX,GS } mov cl,1bh mov ax,301h int 30h { Вывод на экран значения GS } jmp @end
{------Функция 4: Вывод на экран наименований и значений------} {------------битов (флагов) регистра управления CR0-----------} { Назначение регистров: AL - номер подфункции } {-------AL=0: вывод в двоичном виде значений битов CR0--------} {-------AL=1: вывод наименований и значений битов CR0--------} @f4: cmp al,0 jz @val {------------------Вывод массива строк s_CR0------------------} lea bx,s_CR0 mov cx,2 @as2:push cx push bx mov ah,4 mov cl,1dh mov si,bx int 30h add di,96 pop bx add bx,256 pop cx loop @as2 sub di,8 @val: mov ah,4 mov cl,1ah mov si,offset s_CR0n { Вывод строки "CR0:" } int 30h db 0fh,20h,0c2h { MOV EDX,CR0 } mov cl,1bh mov ax,502h int 30h { Вывод на экран значений разрядов CR0 } jmp @end
{------Функция 5: Вывод на экран наименований и значений------} {------------битов (флагов) регистра управления CR4-----------} @f5: {------------------Вывод массива строк s_CR4------------------} lea bx,s_CR4 mov cx,3 @as3:push cx push bx mov ah,4 mov cl,1dh mov si,bx int 30h add di,96 pop bx add bx,256 pop cx loop @as3 sub di,8 mov ah,4 mov cl,1ah mov si,offset s_CR4n { Вывод строки "CR4:" } int 30h db 0fh,20h,0e2h { MOV EDX,CR4 } mov cl,1bh mov ax,502h int 30h { Вывод на экран значений разрядов CR4 } jmp @end {------Функция 6: Вывод на экран наименований и значений------} {----------------битов (флагов) регистра EFLAGS---------------} @f6: {----------------Вывод массива строк s_EFLAGS-----------------} lea bx,s_EFLAGS mov cx,3 @as4:push cx push bx mov ah,4 mov cl,1dh mov si,bx int 30h add di,96 pop bx add bx,256 pop cx loop @as4 sub di,14 mov ah,4 mov cl,1ah mov si,offset s_EFLAGSn int 30h { Вывод строки "EFLAGS:" } db 66h pushf db 66h pop dx mov cl,1bh mov ax,502h int 30h { Вывод на экран значений разрядов EFLAGS } jmp @end {---------Функция 7: Вывод на экран содержимого стека---------} { Назначение регистров: AL - номер подфункции } { AL=0: 16-розрядный стек } { AL=1: 32-розрядный стек } { CX - число элементов стека } @f7: mov bp,sp mov si,0 cmp al,0 jnz @732 @716: push cx push si mov dx,[bp+si] mov ax,301h mov cl,1bh int 30h add di,150 pop si add si,2 pop cx loop @716 jmp @end @732: push cx push si db 66h mov dx,[bp+si+12] mov ax,302h mov cl,1bh int 30h add di,142 pop si add si,4 pop cx loop @732 jmp @end @end: cmp mode,0 jz @iret db 66h @iret:iret end;{int_32nh} {----------Обработчик программного прерывания 33h------------} {----------------Ввод данных с клавиатуры:--------------------} procedure int_33h;assembler; asm {-----------Анализ наличия данных в буфере клавиатуры---------} db 64h mov si,[1ch] { В SI - адрес начала данных } @wait: db 64h cmp si,[1ch] jz @wait cmp ah,2 jnz @end {-----------------------Чтение символа------------------------} db 64h mov dx,[si] { В DL - ASCII-код, в DH - скан-код } {--------Коррекция начала данных в буфере клавиатуры----------} db 64h add si,2 mov [1ah],si @end: db 66h iret end;{int_32h} {==============Секция инициализации модуля PROT===============} begin {---Формирование дескрипторов сегментов базовой таблицы GDT,--} {---------которые являются общими для всех программ,----------} {----------------работающих в защищенном режиме---------------} { Нуль-дескриптор } init_gdt(0,0,0,0,0); { Дескриптор сегмента кода модуля PROT: } init_gdt(PROT_sel,$ffff,longint(CSeg) shl 4,acc_code,0); { Дескриптор сегмента стека: } init_gdt(stack_sel,0,longint(Sseg) shl 4,acc_stack,0); { Дескриптор сегмента данных: } init_gdt(data_sel,$ffff,longint(Dseg) shl 4,acc_data,0); { Дескриптор сегмента данных реального режима: } init_gdt(real_sel,$ffff,longint(Dseg) shl 4,acc_data,0); { Дескриптор сегмента видеопамяти для текстового режима: } init_gdt(text_sel,4000-1,$b8000,acc_data,0); {-----------------------Дескрипторы TSS-----------------------} { Задачи MAIN: } init_gdt(main_sel,sizeof(t_tss)-1, longint(Dseg) shl 4+ofs(main_tss),acc_TSS,0);
{-----Дескриптор шлюза обработчика прерывания от таймера:-----} init_idt($20,ofs(PIC_1),PROT_sel,acc_int); {---Дескриптор шлюза обработчика прерывания от клавиатуры:----} init_idt($21,ofs(keyb),PROT_sel,acc_int); {----Дескрипторы шлюзов обработчиков прерываний IRQ2-IRQ7:----} for i:=2 to 7 do init_idt($20+i,ofs(PIC_1),PROT_sel,acc_int); {---Дескрипторы шлюзов обработчиков прерываний IRQ8-IRQ15:----} for i:=8 to 15 do init_idt($20+i,ofs(PIC_2),PROT_sel,acc_int); {---Дескрипторы шлюза обработчика программного прерывания:----}
init_idt($30,ofs(int_30h),PROT_sel,acc_trap_16); init_idt($31,ofs(int_31h),PROT_sel,acc_trap); init_idt($32,ofs(int_32h),PROT_sel,acc_trap); for i:=$33 to 255 do init_idt(i,0,0,0); {---------Формирование сегмента TSS задачи EXC12_TASK---------} init_tss(exc12_tss,PROT_sel,data_sel,text_sel, ofs(exc12_task),ofs(exc12_stack)+sizeof(exc12_stack)); end.
итог: функция №5 ставите основание 2, и записываете в регистр(к примеру EBX) нужное количество "1", после этого AND EAX,EBX и вывод значения в ЕАХ функция №6 ставите основание 10, и см. выше
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
Здравствуйте, Alexkharkov! Вот Вам реализация функций 5 и 6 В функции 5 сдвигаем edx влево так, чтобы наше число стало на левом крае регистра, затем выводим по тетрадам (раз Вам так хочется менять атрибут у тетрад), начиная со старшего бита В функции 6 мы сначала обнуляем старшие ненужные биты, сдвигая влево/вправо на число ненужных бит, затем формируем в стеке последовательность цифр, как остатки от деления на 10 нашего числа, ну и, наконец, выводим на экран цифры из стека в обратном порядке. [code h=200]{-------Функция 5: вывод данных на экран в двоичной форме-----} { AL=0 - вывод байта } { AL=1 - вывод слова } @f5: { AL=2 - вывод двойного слова } cmp modeVA,0 { определимся с атрибутом } jz @51 mov ah,0f0h { для ч/б } jmp @52 @51: mov ah,cl { заданный атрибут } @52: mov cl,al { размерность данных } mov bx,8 { 8 бит на байт } shl bx,cl { всего бит } mov cx,32 { максимум бит } sub cx,bx { число "лишних" бит слева } db 66h shl dx,cl { сдвинем edx влево, убрав все лишние } mov cx,bx { сколько выводим бит } shr cx,2 { сколько тетрад } @lp_1:push cx { цикл вывода тетрад } xor ah,8 { "помигаем" атрибутом для тетрад } mov cx,4 { число бит в тетраде } @lp_2: { цикл вывода терады, начиная со ст бита } mov al,0 { обнулим } db 66h { сдвинем edx на 1 бит влево, } shl dx,1 { при этом старший бит будет в C } adc al,'0' { al = 0+'0'+C (в итоге '0' или '1') } stosw { пишем } loop @lp_2 { биты тетрады } pop cx { счетчик тетрад } loop @lp_1 { по всем } add di,2 { пропустим одно знакоместо (если надо) } jmp @end
{-----Функция 6: вывод данных на экран в десятичной форме-----} { AL=0 - вывод байта } { AL=1 - вывод слова } @f6: { AL=2 - вывод двойного слова } cmp modeVA,0 { определимся с атрибутом } jz @61 mov bl,0f0h { для ч/б } jmp @62 @61: mov bl,cl { заданный атрибут } @62: mov cl,al { размерность данных } mov ax,8 { 8 бит на байт } shl ax,cl { всего бит } mov cx,32 { максимум бит } sub cx,ax { число "лишних" бит слева } db 66h shl dx,cl { сдвинем edx влево, убрав все лишние } db 66h shr dx,cl { вернем обратно, при этом вместо лишних будут 0 } db 66h mov ax,dx { наше число } xor cx, cx { число цифр } db 66h mov si, 10 { будем делить на dword 10 } dw 0 @6_1: { цикл получения цифр } db 66h xor dx,dx { подготавливаемся к делению } db 66h div si { edx:eax / 10 } push dx { сохраним остаток - очередную младшую цифру } inc cx { считаем } db 66h test ax,ax { eax != 0 ? } jnz @6_1 { т.е. еще есть десятичные разряды? } @6_2: { цикл вывода цифр в обратном порядке } pop ax { извлекаем из стека } mov ah, bl { атрибут } or al, '0' { 0-9 -> '0'-'9' } stosw { пишем } loop @6_2 { по всем } add di,2 { пропустим одно знакоместо (если надо) } jmp @end
end[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, — это верный признак того, что пора меняться." Марк Твен
Форма ответа
Отправка постов/ответов доступна только зарегистрированным и подтвержденным пользователям.
{"canUserNotesAccess":false,"canUserAdminsNotesAccess":false,"canAskQuestion":false,"canEditQuestions":false,"canSeeQuestionsComplains":false,"isSuperAdmin":false,"isAdmin":false,"isModer":false,"canCreateNewUser":false,"canConfirmUser":false,"canEditUserName":false,"canEditUserRole":false,"canEditUserEmail":false,"canEditUserPhone":false,"canEditUserBirthdate":false,"canEditUserCountry":false,"canEditSocialMedia":false,"canDeleteUserPhoto":false,"canDeleteUser":false,"canEditUserAbout":false,"canBanUser":false,"canResetUserPassword":false,"canEditRegistDate":false,"canChangeUserRating":false,"canAccessToAdmin":false,"canAnnouncements":false,"canManageQuestionPosts":false,"canManageForumSections":false,"canManageForumThreads":false,"canManageForumPosts":false,"canCreateForumThreads":false,"canSeeUserEmail":false,"canSeeUserPhone":false,"canSeeIPAddress":false,"canSeeUserRegistDate":false,"canSeeUserSocialMedia":false,"canSeeBirthDate":false,"canSeeUserCountry":false,"canSeeUserSettings":false,"canSeeDeletedPosts":false,"isEmailConfirmed":false,"tel":"","ip":"0.0.0.0","ipLocation":{"ip":"","sDate":0,"postalCode":"","country":"","countryIsoCode":"","federalDistrict":"","region":"","regionType":"","city":"","cityType":"","geoLat":"","geoLon":"","locationString":""},"birthDate":"0001-01-01T00:00:00","age":0,"isBirthdayToday":false,"ban":{"id":0,"userId":0,"isBanned":false,"startDate":"0001-01-01T00:00:00","endDate":"0001-01-01T00:00:00","moder":{"id":0,"name":"Неизвестный","email":"","role":0,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isValid":false,"isLoggedIn":false,"isUnconfirmed":true,"isConfirmed":false,"isNewUser":false,"isExisted":false,"isExpert":false,"isRfproUserClass":false},"reasonHTML":"","timeToUnbanString":"-54 мин."},"isBanned":false,"roleString":"Неподтвержден","roleIcon":"fa-user-clock","socialMedia":[],"aboutText":"","aboutHTML":"","signatureText":"","signatureHTML":"","country":{"id":0,"name":"","isFlagExists":false,"flagImage":"","isValid":false},"city":{"id":0,"name":"","countryId":0,"yandexCityId":0,"isValid":false},"averageEvaluation":0,"absoluteRating":0,"dynamicRating":0,"dynamicRatingStars":0,"timezone":{"id":283,"baseUtcOffset":"03:00:00","displayName":"(UTC\u002B03:00) Москва","linuxid":"Europe/Moscow"},"currentDateTime":"2024-07-04T12:54:56.0467296+03:00","isValid":false,"isUnconfirmed":true,"isConfirmed":false,"settings":{"fixedHeader":true,"fixedFooter":true,"leftColumnMode":2,"darkTheme":false,"topPanelBtns":[{"id":103,"text":"Главная","title":"Главная (начальная) страница Портала","icon":"fa-solid fa-house-chimney","colorClass":"text-info-emphasis","controller":"Home","action":"Index","accessLevel":0,"isDropdown":false},{"id":100,"text":"Вход в систему","title":"Войти в систему с использованием своих регистрационных данных (адрес электронной почты и пароль)","icon":"fa-solid fa-arrow-right-to-bracket","colorClass":"text-info-emphasis","controller":"Login","action":"Index","accessLevel":0,"isDropdown":false},{"id":101,"text":"Регистрация","title":"Зарегистрироваться в системе и стать полноценным участником сообщества","icon":"fa-solid fa-user-plus","colorClass":"text-info-emphasis","controller":"Regist","action":"Index","accessLevel":0,"isDropdown":false},{"id":102,"text":"Сброс пароля","title":"Сбросить пароль свой учетной записи, если Вы его забыли","icon":"fa-solid fa-key","colorClass":"text-danger-emphasis","controller":"Login","action":"ResetPassword","accessLevel":0,"isDropdown":false}],"topPanelBtnsHideText":false},"isLevelUpAllowed":false,"nextRole":1,"counters":{"daysAtPortal":0,"questions":0,"questionsPosts":0,"questionsAnswers":0,"questionsPostsEvaluations":0,"forumPosts":0},"isRfproUserClass":true,"id":0,"name":"Неизвестный","email":"","role":0,"registDate":"0001-01-01T00:00:00","lastDate":"0001-01-01T00:00:00","photo":"images/unophoto.png?v=9.4.12","lastDateIndicatorClass":"gray","lastDateIndicatorText":"давно","photoPreview200":"images/unophoto.png?v=9.4.12","photoPreview120":"images/unophoto.png?v=9.4.12","photoPreview100":"images/unophoto.png?v=9.4.12","photoPreview80":"images/unophoto.png?v=9.4.12","photoPreview40":"images/unophoto.png?v=9.4.12","isPhotoExists":false,"isLoggedIn":false,"isNewUser":false,"isExisted":false,"isExpert":false}