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