3

I've been trying for over 3 hours to figure out what's wrong with the next program. All I'm trying to do is to divide x in y, and then print the result of the division and the modulo. Also, the printf of the modulo, with the % inside, messes all up. Does anyone know how to fix that? I'm working on assembly IA32. Assume I get x and y from the user already.

.section .rodata format1: .string "Div : %d / %d = %d\n" format2: .string "Mod : %d % %d = %d\n" .text .globl main .type main, @function # operation divide movl x, %eax cltd idivl y pushl %eax pushl y pushl x pushl $format1 call printf # operation modulo pushl %edx pushl y pushl x pushl $format2 call printf 

I know the modulo should be kept in the %edx register, so why it doesnt work? Thanks alot! D:

edit: Ok, so I saved %edx in %ebx and now the modulo works fine. (if I print what's in %edx it gives the right modulo) But the print to the screen still not what I want. This is the output for x=2, y=4:

Divide : 2 / 4 = 0 Modulo : 2 %d = 4 

and I want it to look like this:

Divide : 2 / 4 = 0.50 Modulo : 2 % 4 = 2 
4
  • maybe printf is changing the contents of the register Commented Nov 24, 2012 at 17:35
  • I dont think so, ive tried other operands such as multiply and it worked fine Commented Nov 24, 2012 at 17:41
  • What's the input, the current output, and the expected output? Commented Nov 24, 2012 at 17:42
  • You're not clearing your stack and you're not saving your registers before the call to printf. Commented Nov 24, 2012 at 17:43

2 Answers 2

2

EAX, ECX and EDX are caller saved registers, this means you must save them before calling printf, which is at liberty to change any of those registers without restoring them.

EBX, ESI and EDI on the other hand are callee-saved, which means every function needs to restore them to their original contents before the call.

Sign up to request clarification or add additional context in comments.

Comments

2

According to the System V ABI for Intel386, functions are allowed to use %ecx and %edx as scratch registers and callees don't have to preserve their value for the caller. This means, that printf is allowed to overwrite the value of %edx, thus destroying the value of the reminer. You could save it by transfering the value of %edx to %esi or %edi, as per the specification their value has to be preserved by the callees (they "belong" to the caller).

This said, you have an error in format2. You should change it to:

format2: .string "Mod : %d %% %d = %d\n" 

Literal % must be written as %% in the format string, otherwise it will be iterpreted as a format specifier by printf.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.