1

The code Should work like this: read a character from the input and look if it is a uppercase Letter repeat the reading until a non uppercase character is read in print out all the uppercase characters starting with the newest read in letter for example: A B C E f

E C B A .... my question would be how do i use the stack to find out if every letter has been printed when is the end reached. and if the first read in char is a non uppercase char it should print out an error message

Start:  
    call    read_char         ;reading a char and comparing if it is a uppercase letter
    mov     ebx,eax
    call    read_char          ;if a non uppercase letter is read in jump to print label

    cmp    ebx,65
    jb     PrintChar

    cmp   ebx,90
    ja    PrintChar
    
    push    ebx             ;pushing the char onto the stack and repeating the process
    
    jmp     Start

    
PrintChar:
loop:
    pop     eax                      ;pop the char from the stack to the eax register and print it
    call    print_char               

    jmp     loop                     ;repeat this process until all char are printed out (this code is not written)
    

MessageFail:

    mov      eax,msg_fail                          ;if the stack was empty (the first input a lovercase letter) print a fail message
    call    print_string
    call    print_nl
    jmp     Ende
Ende:
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
ineedhelp
  • 25
  • 3
  • 1
    I've formatted your code so it is valid and easier to read. Please let me know if the new formatting is incorrect (or update inline). – h0r53 Jan 03 '22 at 22:42
  • 1
    "how do i use the stack to find out if every letter has been printed when is the end reached?" - You could always push a special character onto the stack before starting, and during your print `loop` you can check to see if you encounter this special character. I would of course not use a character in the range of uppercase ASCII, as that would cause issues. Perhaps simply `push 0x0` onto the stack to start with and check for that after `pop eax ` – h0r53 Jan 03 '22 at 22:44
  • 2
    (a) You can count how many items you're pushing on the stack, and when you pop that many, it's done. (b) You can capture the value of the stack pointer before you start, and during popping when the stack pointer reaches that value, you're done. (c) You can push some terminal value onto the stack before you start, and when you see that value, it's done. I'd probably pick (b) since it doesn't require counting, or pushing/testing for a terminal value (instead (b) uses a terminal address). – Erik Eidt Jan 03 '22 at 22:54

1 Answers1

3

"How do I use the stack to find out if every letter has been printed when is the end reached?"

You could always push a special character onto the stack before starting, and during your print loop you can check to see if you encounter this special character before printing. If you do, then instead jump to Ende. I would of course not use a character in the range of uppercase ASCII, as that would cause issues. Perhaps simply push 0x0 onto the stack to start with and check for that after pop eax in loop. Something like this:

Start:
    push    0x0               ; push 0x0 onto the stack to denote the beginning
ReadChars:
    call    read_char         ;reading a char and comparing if it is a uppercase letter
    mov     ebx,eax

    cmp    ebx,65
    jb     PrintChar

    cmp   ebx,90
    ja    PrintChar
    
    push    ebx             ;pushing the char onto the stack and repeating the process
    
    jmp     ReadChars

    
PrintChar:
loop:
    pop     eax                      ;pop the char from the stack to the eax register and print it

    test    eax, eax            ; test if eax=0
    jz      Ende             ; jump to end if eax was zero
    call    print_char               

    jmp     loop                     ;repeat this process until all char are printed out (this code is not written)
    

MessageFail:

    mov     eax,msg_fail                          ;if the stack was empty (the first input a lovercase letter) print a fail message
    call    print_string
    call    print_nl
    jmp     Ende
Ende:

As far as printing an error message if the first character is out of range, I think you could always use a spare register to store whether or not you are operating on the first character. Let's say you used ecx to store this. Then in Start initialize ecx to 0x0 and at the end of ReadChars update ecx to 0x1. Then, if ecx is zero and the character you read is not within the uppercase ASCII range, you know that the user entered an invalid character sequence, and you can jump to MessageFail

h0r53
  • 3,034
  • 2
  • 16
  • 25
  • I am new to Assembly could you maybe explain what test does is it similar to cmp? – ineedhelp Jan 03 '22 at 22:57
  • 2
    `test` performs a BITWISE AND on the two operands and sets the `ZERO FLAG` if the result is zero. The only way a BITWISE AND on a register and itself results in zero is if the register contains the number zero, so `test` followed by `jz` is a quick way to check if a number is zero and conditionally jump. – h0r53 Jan 03 '22 at 23:01
  • 1
    Yes this is similar to `cmp`, and you could alternatively use `cmp`. I believe `test` requires less cycles than `cmp` though, since a BITWISE AND is very fast and I want to say `cmp` uses subtraction to compare numbers (but I can't find a source for that so I may be wrong). – h0r53 Jan 03 '22 at 23:04
  • 3
    @ineedhelp: See [Test whether a register is zero with CMP reg,0 vs OR reg,reg?](https://stackoverflow.com/a/33724806) for why `test reg,reg` is identical to `cmp reg,0`, but smaller and more efficient. – Peter Cordes Jan 03 '22 at 23:15
  • 1
    I finished the code and everything worked thanks ! – ineedhelp Jan 03 '22 at 23:20