Исправить код! - Assembler

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток. Есть задание. Требуется: 1) Ввести текст с клавиатуры и записать его в память ЭВМ. 2) Определить, начинается ли и оканчивается ли этот текст цифрой, причём эти цифры различны. 3) Если текст обладает свойством из пункта 2, то заменить каждую ненулевую цифру соответствующей ей по порядковому номеру строчной буквой латинского алфавита. Иначе повторить каждый символ текста. 4) Вывести на экран исходный и преобразованный тексты. Вот написал код на С:
#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;
}
Из этого в 2010 студии получился листинг: В Debug:
; 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
И в Release:
; 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
Помогите исправить ассемблерный код, чтобы на work32c.bat всё заработало. Очень прошу!!!

Решение задачи: «Исправить код!»

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

Объяснение кода листинга программы

  1. Переменная ecx получает значение length_.
  2. В регистре esi хранится адрес начала строки s.
  3. В регистре edi хранится адрес строки s.
  4. Начинается цикл, в котором происходит следующее:
    • Получаем в регистр AL код очередного символа.
    • Сравниваем AL с началом диапазона (цифра 1), если меньше, то переходим к следующему символу.
    • Если AL больше конца диапазона (цифра 9), то также переходим к следующему символу.
    • Добавляем к AL 30h (для преобразования цифр в буквы).
    • Отправляем символ обратно в строку.
  5. Цикл повторяется до тех пор, пока не будет пройдена вся строка.

Оцени полезность:

14   голосов , оценка 3.929 из 5