Author Topic: Multiple Procedures?  (Read 5753 times)

Offline dominick

  • Jr. Member
  • *
  • Posts: 9
Multiple Procedures?
« on: August 07, 2011, 03:17:51 PM »
Hello,

 I'm having trouble getting multiple procedures to work together... they both work fine alone... but the second one (WriteInteger) messes up when incorporated into code with the first (WriteString) and I'm trying to understand why.

Here's the code I'm looking at:

Code: [Select]
org 0x100
section .data
Constant0 db "hello"
Constant0length equ 5
Newline db 13, 10
Newlinelength equ 2
Constant2 equ 1 ; trouble here (do I make it a dd, dw, or just leave it as equ?)

section .text
and esp, 0FFFFh
push Constant0length
push Constant0
Call WriteString
push Newlinelength
push Newline
Call WriteString
push Constant2 ; trouble here?
Call WriteInteger
push Newline
push Newlinelength
Call WriteString
mov ax, 0x4c00
int 0x21
WriteString:
mov si, [esp + 2]
mov cx, [esp + 4]
strtoconsole:
lodsb
mov dl, al
mov ah, 0x06
int 0x21
loop strtoconsole
.end:
ret 4
WriteInteger: ; trouble here?
mov eax, [esp + 2] ; move number into eax.
mov ecx, 10 ; move 10 into ecx
xor bx, bx ; zero out bx
divide:
xor edx, edx ; zero out edx
div ecx ; divide eax by ecx
push dx ; push dx (digit to print)
inc bx ; increment bx
test eax, eax ; test eax for zero
jnz divide ; if eax isn't zero then divide further
mov cx, bx ; move bx (number of digits) to cx (code counter)
outputDigit:
pop ax ; pop ax
add al, '0' ; add integer '0' to al to make al an regular text (numeric) character.
mov dl, al ; move al into dl.
mov ah, 0x06 ; character ouput.
int 0x21 ; execute character output
loop outputDigit ; loop until cx is zero
ret 2

 As always, thanks in advance for any help you can give,

 Dominick

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Multiple Procedures?
« Reply #1 on: August 07, 2011, 06:16:16 PM »
First thing I see is that you've reversed the pushes of "string" and "length" before your very last call to WriteString. Easily fixed.

Now... constant2 is an equ. That'll work, but it might be more useful to make it a dw... or dd... and that's a hint to what's wrong... In WriteInteger, you do:

Code: [Select]
mov eax, [esp + 2]

That gets 4 bytes into eax - the two you've pushed, and... who knows what? It is possible, if a little unusual, to push 4 bytes in 16-bit code...

Code: [Select]
push dword constant2

... or if it's a dd variable,

Code: [Select]
push dword [myvar]

Or... you could just use ax in WriteInteger. If you go with the dword, you need "ret 4" to clean up the stack.

That's all I see at the moment. (must get dosemu working or install dosbox so I can test these things!)

Best,
Frank


Offline dominick

  • Jr. Member
  • *
  • Posts: 9
Re: Multiple Procedures?
« Reply #2 on: August 07, 2011, 08:24:36 PM »
Ok, here's what I've come up with, and it seems to work just fine. Thanks for your help Frank.  :)

Code: [Select]
org 0x100
section .data
Constant0 db "hello"
Constant0length equ 5

Newline db 13, 10
Newlinelength equ 2

Constant2 equ 1


section .text
And esp, 0x0ffff
push Constant0length
push Constant0
Call WriteString
push Newlinelength
push Newline
Call WriteString
push dword Constant2
Call WriteInteger
push Newlinelength
push Newline
Call WriteString
mov ax, 0x4c00
int 0x21
WriteString:
mov si, [esp + 2]
mov cx, [esp + 4]
strtoconsole:
lodsb
mov dl, al
mov ah, 0x06
int 0x21
loop strtoconsole
.end:
ret 2
WriteInteger:
mov eax, [esp + 2]
mov ecx, 10
xor bx, bx
divide:
xor edx, edx
div ecx
push dx
inc bx
test eax, eax
jnz divide
mov cx, bx
outputDigit:
pop ax,
add al, '0'
mov dl, al
mov ah, 0x06
int 0x21
loop outputDigit
ret 4