BUG Fix bug in 64-bit subroutine lesson. Streamline 32-bit subroutine lesson.
There was a bug in the 64-bit subroutine lesson that popped the stack once too many times: there were two pushes but three pops. That this didn't generate a stack underflow condition confuses and worries me. I would have expected a segfault when I decremented the stack counter once too often. This makes me wonder if I understand this program well enough. The effect on the registers was, fortunately, harmless as the next step completely repurposed the registers to initialize the exit() routine. Once I'd figured out how to use the RSI and RAX registers correctly, I streamlined the 32-bit version so that the products of strlen(), the start and length of the message, were already in the registers when I issued my syscall to WRITE(). I'm sure this is, in some ways, *bad* assembly, but I'm not (yet) an ASM stylist.
This commit is contained in:
		
							parent
							
								
									127e5c0b71
								
							
						
					
					
						commit
						89b58186fb
					
				|  | @ -17,45 +17,36 @@ section .text | |||
|     global _start | ||||
| 
 | ||||
| _start: | ||||
|     mov     eax, msg            ; Put the address of our message into eax.
 | ||||
|     mov     ecx, msg            ; Put the address of our message into eax.
 | ||||
|     call    strlen              ; call the function strlen.  We're using EAX as our argument.
 | ||||
| 
 | ||||
|     mov     edx, eax            ; We know printit wants these two
 | ||||
|     mov     eax, msg | ||||
|     call    printit | ||||
|     call    exit | ||||
| 
 | ||||
| strlen: | ||||
|     push    ebx                 ; Push ebx onto the stack, since the calling scope
 | ||||
|                                 ; will probably want its state restored correctly, right?
 | ||||
|     mov     ebx, eax | ||||
|     mov     edx, ecx | ||||
| 
 | ||||
| strlen_next: | ||||
|     cmp     byte [eax], 0 | ||||
|     cmp     byte [edx], 0 | ||||
|     jz      strlen_done | ||||
|     inc     eax | ||||
|     inc     edx | ||||
|     jmp     strlen_next | ||||
| 
 | ||||
| strlen_done: | ||||
|     sub     eax, ebx            ; Straight from the counted-hello file
 | ||||
|     pop     ebx                 ; restore EBX for the calling scope, which is
 | ||||
|                                 ; expecting its answer in eax
 | ||||
|     sub     edx, ecx            ; Straight from the counted-hello file
 | ||||
|     ret | ||||
| 
 | ||||
|     ;; Takes EAX as the address of the message and EDX as the
 | ||||
|     ;; length, and prints them.  Restores all used registers
 | ||||
|     ;; when finished.
 | ||||
|     ;; when finished.  EDX contains the count.
 | ||||
| printit: | ||||
|     push    eax | ||||
|     push    ebx | ||||
|     push    ecx | ||||
|     mov     ecx, eax | ||||
|     push    eax | ||||
|     mov     ebx, STDOUT | ||||
|     mov     eax, SYS_write | ||||
|     int     80h | ||||
|     pop     ecx | ||||
|     pop     ebx | ||||
|     pop     eax | ||||
|     pop     ebx | ||||
|     ret | ||||
| 
 | ||||
|     ;; Since this terminates the program, I'm not worried about
 | ||||
|  |  | |||
|  | @ -55,7 +55,6 @@ printit: | |||
|     mov     rax, SYS_write      ; Using WRITE in 32-bit mode?
 | ||||
|     syscall | ||||
|     pop     rax | ||||
|     pop     rdx | ||||
|     pop     rdi | ||||
| 
 | ||||
|     ;; Since this terminates the program, I'm not worried about
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue