From 89b58186fbc54508891c0077cc3e32b3fed8d7cb Mon Sep 17 00:00:00 2001 From: "Elf M. Sternberg" Date: Fri, 27 Apr 2018 16:44:37 -0700 Subject: [PATCH] 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. --- subroutine-hello32.s | 25 ++++++++----------------- subroutine-hello64.s | 1 - 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/subroutine-hello32.s b/subroutine-hello32.s index d4a7505..a918e69 100644 --- a/subroutine-hello32.s +++ b/subroutine-hello32.s @@ -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 diff --git a/subroutine-hello64.s b/subroutine-hello64.s index dafc3d1..bb4f000 100644 --- a/subroutine-hello64.s +++ b/subroutine-hello64.s @@ -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