Исправить код! - Assembler
Формулировка задачи:
Доброго времени суток.
Есть задание. Требуется:
1) Ввести текст с клавиатуры и записать его в память ЭВМ.
2) Определить, начинается ли и оканчивается ли этот текст цифрой, причём эти цифры различны.
3) Если текст обладает свойством из пункта 2, то заменить каждую ненулевую цифру соответствующей ей по порядковому номеру строчной буквой латинского алфавита. Иначе повторить каждый символ текста.
4) Вывести на экран исходный и преобразованный тексты.
Вот написал код на С:
Из этого в 2010 студии получился листинг:
В Debug:
И в Release:
Помогите исправить ассемблерный код, чтобы на work32c.bat всё заработало.
Очень прошу!!!
#include <stdio.h> #include <stdlib.h> int main() { char s[100]; int length; int i; scanf ("%s", s); length = strlen(s); for (i = 1; i < length - 1; i++) { if (s[i] == '1') s[i] = 'a'; if (s[i] == '2') s[i] = 'b'; if (s[i] == '3') s[i] = 'c'; if (s[i] == '4') s[i] = 'd'; if (s[i] == '5') s[i] = 'e'; if (s[i] == '6') s[i] = 'f'; if (s[i] == '7') s[i] = 'g'; if (s[i] == '8') s[i] = 'h'; if (s[i] == '9') s[i] = 'i'; } printf("%s", s); getchar(); return 0; }
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 TITLE c:\Users\LENOVO\documents\visual studio 2010\Projects\sosnitski\sosnitski\sosnitsky.c .686P .XMM include listing.inc .model flat INCLUDELIB MSVCRTD INCLUDELIB OLDNAMES PUBLIC ??_C@_02DKCKIIND@?$CFs?$AA@ ; `string' PUBLIC __$ArrayPad$ PUBLIC _main EXTRN __imp__getchar:PROC EXTRN __imp__printf:PROC EXTRN _strlen:PROC EXTRN __imp__scanf:PROC EXTRN ___security_cookie:DWORD EXTRN @__security_check_cookie@4:PROC EXTRN @_RTC_CheckStackVars@8:PROC EXTRN __RTC_CheckEsp:PROC EXTRN __RTC_Shutdown:PROC EXTRN __RTC_InitBase:PROC ; COMDAT ??_C@_02DKCKIIND@?$CFs?$AA@ ; File c:\users\lenovo\documents\visual studio 2010\projects\sosnitski\sosnitski\sosnitsky.c CONST SEGMENT ??_C@_02DKCKIIND@?$CFs?$AA@ DB '%s', 00H ; `string' CONST ENDS ; COMDAT rtc$TMZ rtc$TMZ SEGMENT __RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown rtc$TMZ ENDS ; COMDAT rtc$IMZ rtc$IMZ SEGMENT __RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase ; Function compile flags: /Odtp /RTCsu /ZI rtc$IMZ ENDS ; COMDAT _main _TEXT SEGMENT _i$ = -132 ; size = 4 _length$ = -120 ; size = 4 _s$ = -108 ; size = 100 __$ArrayPad$ = -4 ; size = 4 _main PROC ; COMDAT ; 5 : { push ebp mov ebp, esp sub esp, 328 ; 00000148H push ebx push esi push edi lea edi, DWORD PTR [ebp-328] mov ecx, 82 ; 00000052H mov eax, -858993460 ; ccccccccH rep stosd mov eax, DWORD PTR ___security_cookie xor eax, ebp mov DWORD PTR __$ArrayPad$[ebp], eax ; 6 : char s[100]; ; 7 : int length; ; 8 : int i; ; 9 : scanf ("%s", s); mov esi, esp lea eax, DWORD PTR _s$[ebp] push eax push OFFSET ??_C@_02DKCKIIND@?$CFs?$AA@ call DWORD PTR __imp__scanf add esp, 8 cmp esi, esp call __RTC_CheckEsp ; 10 : length = strlen(s); lea eax, DWORD PTR _s$[ebp] push eax call _strlen add esp, 4 mov DWORD PTR _length$[ebp], eax ; 11 : for (i = 1; i < length - 1; i++) mov DWORD PTR _i$[ebp], 1 jmp SHORT $LN12@main $LN11@main: mov eax, DWORD PTR _i$[ebp] add eax, 1 mov DWORD PTR _i$[ebp], eax $LN12@main: mov eax, DWORD PTR _length$[ebp] sub eax, 1 cmp DWORD PTR _i$[ebp], eax jge $LN10@main ; 12 : { ; 13 : if (s[i] == '1') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 49 ; 00000031H jne SHORT $LN9@main ; 14 : s[i] = 'a'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 97 ; 00000061H $LN9@main: ; 15 : if (s[i] == '2') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 50 ; 00000032H jne SHORT $LN8@main ; 16 : s[i] = 'b'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 98 ; 00000062H $LN8@main: ; 17 : if (s[i] == '3') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 51 ; 00000033H jne SHORT $LN7@main ; 18 : s[i] = 'c'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 99 ; 00000063H $LN7@main: ; 19 : if (s[i] == '4') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 52 ; 00000034H jne SHORT $LN6@main ; 20 : s[i] = 'd'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 100 ; 00000064H $LN6@main: ; 21 : if (s[i] == '5') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 53 ; 00000035H jne SHORT $LN5@main ; 22 : s[i] = 'e'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 101 ; 00000065H $LN5@main: ; 23 : if (s[i] == '6') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 54 ; 00000036H jne SHORT $LN4@main ; 24 : s[i] = 'f'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 102 ; 00000066H $LN4@main: ; 25 : if (s[i] == '7') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 55 ; 00000037H jne SHORT $LN3@main ; 26 : s[i] = 'g'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 103 ; 00000067H $LN3@main: ; 27 : if (s[i] == '8') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 56 ; 00000038H jne SHORT $LN2@main ; 28 : s[i] = 'h'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 104 ; 00000068H $LN2@main: ; 29 : if (s[i] == '9') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 57 ; 00000039H jne SHORT $LN1@main ; 30 : s[i] = 'i'; mov eax, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+eax], 105 ; 00000069H $LN1@main: ; 31 : } jmp $LN11@main $LN10@main: ; 32 : printf("%s", s); mov esi, esp lea eax, DWORD PTR _s$[ebp] push eax push OFFSET ??_C@_02DKCKIIND@?$CFs?$AA@ call DWORD PTR __imp__printf add esp, 8 cmp esi, esp call __RTC_CheckEsp ; 33 : getchar(); mov esi, esp call DWORD PTR __imp__getchar cmp esi, esp call __RTC_CheckEsp ; 34 : return 0; xor eax, eax ; 35 : } push edx mov ecx, ebp push eax lea edx, DWORD PTR $LN17@main call @_RTC_CheckStackVars@8 pop eax pop edx pop edi pop esi pop ebx mov ecx, DWORD PTR __$ArrayPad$[ebp] xor ecx, ebp call @__security_check_cookie@4 add esp, 328 ; 00000148H cmp ebp, esp call __RTC_CheckEsp mov esp, ebp pop ebp ret 0 npad 2 $LN17@main: DD 1 DD $LN16@main $LN16@main: DD -108 ; ffffff94H DD 100 ; 00000064H DD $LN15@main $LN15@main: DB 115 ; 00000073H DB 0 _main ENDP _TEXT ENDS END
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 TITLE c:\Users\LENOVO\documents\visual studio 2010\Projects\sosnitski\sosnitski\sosnitsky.c .686P .XMM include listing.inc .model flat INCLUDELIB OLDNAMES EXTRN @__security_check_cookie@4:PROC EXTRN __imp__getchar:PROC EXTRN __imp__printf:PROC EXTRN __imp__scanf:PROC $SG-5 DB '%s', 00H ORG $+1 $SG-6 DB '%s', 00H PUBLIC __$ArrayPad$ PUBLIC _main EXTRN ___security_cookie:DWORD ; Function compile flags: /Odtp ; File c:\users\lenovo\documents\visual studio 2010\projects\sosnitski\sosnitski\sosnitsky.c ; COMDAT _main _TEXT SEGMENT tv68 = -136 ; size = 4 tv150 = -129 ; size = 1 tv147 = -128 ; size = 4 tv144 = -124 ; size = 4 _s$ = -120 ; size = 100 __$ArrayPad$ = -12 ; size = 4 _i$ = -8 ; size = 4 _length$ = -4 ; size = 4 _main PROC ; COMDAT ; 5 : { push ebp mov ebp, esp sub esp, 136 ; 00000088H mov eax, DWORD PTR ___security_cookie xor eax, ebp mov DWORD PTR __$ArrayPad$[ebp], eax ; 6 : char s[100]; ; 7 : int length; ; 8 : int i; ; 9 : scanf ("%s", s); lea eax, DWORD PTR _s$[ebp] push eax push OFFSET $SG-5 call DWORD PTR __imp__scanf add esp, 8 ; 10 : length = strlen(s); lea ecx, DWORD PTR _s$[ebp] mov DWORD PTR tv144[ebp], ecx mov edx, DWORD PTR tv144[ebp] add edx, 1 mov DWORD PTR tv147[ebp], edx $LL15@main: mov eax, DWORD PTR tv144[ebp] mov cl, BYTE PTR [eax] mov BYTE PTR tv150[ebp], cl add DWORD PTR tv144[ebp], 1 cmp BYTE PTR tv150[ebp], 0 jne SHORT $LL15@main mov edx, DWORD PTR tv144[ebp] sub edx, DWORD PTR tv147[ebp] mov DWORD PTR tv68[ebp], edx mov eax, DWORD PTR tv68[ebp] mov DWORD PTR _length$[ebp], eax ; 11 : for (i = 1; i < length - 1; i++) mov DWORD PTR _i$[ebp], 1 jmp SHORT $LN12@main $LN11@main: mov ecx, DWORD PTR _i$[ebp] add ecx, 1 mov DWORD PTR _i$[ebp], ecx $LN12@main: mov edx, DWORD PTR _length$[ebp] sub edx, 1 cmp DWORD PTR _i$[ebp], edx jge $LN10@main ; 12 : { ; 13 : if (s[i] == '1') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 49 ; 00000031H jne SHORT $LN9@main ; 14 : s[i] = 'a'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 97 ; 00000061H $LN9@main: ; 15 : if (s[i] == '2') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 50 ; 00000032H jne SHORT $LN8@main ; 16 : s[i] = 'b'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 98 ; 00000062H $LN8@main: ; 17 : if (s[i] == '3') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 51 ; 00000033H jne SHORT $LN7@main ; 18 : s[i] = 'c'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 99 ; 00000063H $LN7@main: ; 19 : if (s[i] == '4') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 52 ; 00000034H jne SHORT $LN6@main ; 20 : s[i] = 'd'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 100 ; 00000064H $LN6@main: ; 21 : if (s[i] == '5') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 53 ; 00000035H jne SHORT $LN5@main ; 22 : s[i] = 'e'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 101 ; 00000065H $LN5@main: ; 23 : if (s[i] == '6') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 54 ; 00000036H jne SHORT $LN4@main ; 24 : s[i] = 'f'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 102 ; 00000066H $LN4@main: ; 25 : if (s[i] == '7') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 55 ; 00000037H jne SHORT $LN3@main ; 26 : s[i] = 'g'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 103 ; 00000067H $LN3@main: ; 27 : if (s[i] == '8') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 56 ; 00000038H jne SHORT $LN2@main ; 28 : s[i] = 'h'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 104 ; 00000068H $LN2@main: ; 29 : if (s[i] == '9') mov eax, DWORD PTR _i$[ebp] movsx ecx, BYTE PTR _s$[ebp+eax] cmp ecx, 57 ; 00000039H jne SHORT $LN1@main ; 30 : s[i] = 'i'; mov edx, DWORD PTR _i$[ebp] mov BYTE PTR _s$[ebp+edx], 105 ; 00000069H $LN1@main: ; 31 : } jmp $LN11@main $LN10@main: ; 32 : printf("%s", s); lea eax, DWORD PTR _s$[ebp] push eax push OFFSET $SG-6 call DWORD PTR __imp__printf add esp, 8 ; 33 : getchar(); call DWORD PTR __imp__getchar ; 34 : return 0; xor eax, eax ; 35 : } mov ecx, DWORD PTR __$ArrayPad$[ebp] xor ecx, ebp call @__security_check_cookie@4 mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END
Решение задачи: «Исправить код!»
textual
Листинг программы
mov ecx,length_; в ассемблере length служебное слово и его нельзя использовать для названия переменной lea esi,s;в регистре esi адрес начала строки s mov edi,esi @1: lodsb;получаем в регистр AL код очередного символа cmp al,'1'; сравниваем с началом диапазона, если меньше тогда переходим к следующему символу jb @2 cmp al,'9'; сравниваем с концом диапазона, если больше тогда переходим к следующему символу ja @2 add al,30h; преобразуем коды цифр в буквы @2: stosb; отправляем символ обратно в строку loop @1
Объяснение кода листинга программы
- Переменная
ecx
получает значениеlength_
. - В регистре
esi
хранится адрес начала строкиs
. - В регистре
edi
хранится адрес строкиs
. - Начинается цикл, в котором происходит следующее:
- Получаем в регистр
AL
код очередного символа. - Сравниваем
AL
с началом диапазона (цифра 1), если меньше, то переходим к следующему символу. - Если
AL
больше конца диапазона (цифра 9), то также переходим к следующему символу. - Добавляем к
AL
30h (для преобразования цифр в буквы). - Отправляем символ обратно в строку.
- Получаем в регистр
- Цикл повторяется до тех пор, пока не будет пройдена вся строка.