Hi!
I'm wondering how to perform:
"To read and write call interrupts using instruction int (e.g. int 10h)."
(in nasm x86)

for example:

bits 32
extern _printf, _scanf
global _main

section .data
    message db "Hello!", 10, 0
section .text
_main:
      pushad

      push dword message
      call _printf        <--- how to?      
      add esp, 4

      popad
      ret

and

bits 32
extern _printf, _scanf
global _main

section .bss
    value resd 1
section .data
    message db "Hello!", 10, 0
    handler db "%d"

section .text
_main:
      pushad

      push dword value
      push dword handler
      call _scanf        <--- how to?      
      add esp, 8

      popad
      ret

So I need to use int instruction instead of _scanf and _printf..

Any advise?

thanx in advance!

Dani AI

Generated

Short answer: you cannot make the C library routines printf/scanf happen by firing an interrupt. Those are user‑space libc functions (they sit in glibc or another C library) and themselves use kernel syscalls to do IO. To get formatted I/O from assembly either call the C functions (link with libc) or invoke kernel syscalls and implement parsing/formatting in your code. (man7.org)

Since you said you are on Linux, the kernel syscall path on 32‑bit i386 is int 0x80. The convention is: put the syscall number in EAX and the first three args in EBX, ECX, EDX (more args use ESI, EDI, EBP); the kernel returns the result in EAX. For example, write/read are ordinary syscalls (write maps to the kernel write call). Common mistakes that stop your int 0x80 attempt are: not setting EBX (the file descriptor — use 1 for stdout), declaring the message with the wrong size directive (use byte data), or computing the length incorrectly. (cs.umb.edu)

If you prefer to call libc functions from NASM, assemble and link the usual way and obey the C calling convention: declare extern printf (no leading underscore on Linux), global main (or let GCC provide _start), push or place arguments according to the platform ABI, call the function, and clean the stack if you used cdecl. Using gcc to link (instead of raw ld) is the simplest way to pull in libc correctly. (nasm.us)

Quick checklist for troubleshooting

  • Decide: raw syscall (int 0x80) or libc call.
  • For syscalls: set EAX=syscall, EBX=fd, ECX=buf, EDX=len; check data is db and length is $-label.
  • For libc: use extern printf / global main, follow the ABI, link with gcc (or add -lc), and push pointers, not values.
  • Note: int 0x80 is the 32‑bit interface; x86_64 uses the syscall instruction and a different register layout. (john-millikin.com)

Typos and platform mismatches are the usual cause here. was right that interrupts are OS-provided; was right to ask platform; , pick one of the two approaches above and adjust the small issues (EBX/file‑descriptor, db vs dw, symbol names and link commands) and it will work.

Recommended Answers

All 9 Replies

int instructions only work for the interrupt functions that are pre-defined by the operating system. printf() and scanf() are not define by the os api therefore it's not possible to perform int instructions to access them. Those are higher-level functions defined by the C language. google for int 21 instructions and you will find a list of all available functions for int 21.

bits 32
extern _printf, _scanf
global _main

section .data
    message dw "Hello!"
    lenmessage equ $-message
section .text
_main:
      pushad

      mov edx, lenmessage   ;count of bytes for write syscall
      mov ecx, message      ;poiter to output buffer
      mov eax, 4            ;syscall write
      int 0x80              ;make call

      popad
      ret

I tried something like this but its still not working...
Help?

Why are you just tossing int instructions around hoping that someday one of them might work????

Because I don't know what to do.

Well then buy a book on assembly programming or read some online tutorials. Anything is better than blindly guessing.

I have read: - PC Assembly Language by Paul A. Carter
- http://www.daniweb.com/forums/thread41309.html (pdf)
Guess what? Nothing about interrupts.

Why do you think I'm asking help here? Is that because I know how to solved it? you're wrong my friend...

What platform are you using, as there is a distinct way of calling interrupts through BIOS, DOS or LINUX.

These calling conventions allow you to access hardware directly (BIOS) or near directly (DOS). Windows just won't allow you to do it at all.

This page deliniates how to use INT 10 Video

I'm using Linux.

In Linux INT 80 is probably the best option. This site will probably be a good resource.

I have limited experience with Linux, but have had enough exposure in the past that I may be able to help with specifics

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.