How to write an Assembly (NASM) subroutine

Asked 2 years ago, Updated 2 years ago, 46 views

I'm starting to learn the assembler (NASM) in an x86 environment.
I want to learn how to write subroutines, so I'm trying to write down the code at the code at the bottom.
What do you expect is

Hello, World
Japan

I would like to print it out, but when I run the code at the bottom, it will output as follows:

Hello, World
Japan
Japan

As for the image, I think that the subroutine of test in line 17 is running the process of outputting Japan, but it seems that the test: part is running without a call.
How can I code it to work only as a subroutine?

1 section.data
  2 message db 'Hello, World', 0x0a
  3 message 2 db 'Japan', 0x0a
  4
  5 length equal $-message
  6 length 2equ$-message2
  7 section.text
  8global_start
  9
 10_start:
 11 move cx, message
 12movedx, length
 13 moveax, 4
 14 movebx, 1
 15 int 0x80
 16
 17 call test
 18
 19 moveax, 1
 20 movebx, 0 
 21         int     0x80
 22
 23         test:
 24                 mov     ecx, message2
 25                 mov     edx, length2
 26                 mov     eax, 4
 27                 mov     ebx, 1
 28                 int 0x80
 29                 ret

linux

2022-09-30 18:44

1 Answers

At the end of your code main routine,

19moveax,1
 20 movebx, 0 
 21         int     0x80

and the call to sys_exit, so the subroutine test should not run beyond that.
(I don't think it's necessary to set a value for ebx, but it should be harmless for now.)

This is the reason why Japan appears twice.

 2 message db 'Hello, World', 0x0a
  3 message 2 db 'Japan', 0x0a
  4
  5 length equal $-message
  6 length 2equ$-message2

By this definition, length calculates the length from the beginning of message to the current location ($), so the length must exceed the label message2 and include all of 'Hello, World', 0x0a, 'Japan', 0x0a'.

11 move cx, message
 12movedx, length
 13 moveax, 4
 14 movebx, 1
 15 int 0x80

As a result, if you do the above in the main routine, you will be able to see up to the Japan part.

To get your desired behavior done, rewrite lines 2 through 6 as follows:

 2 message db 'Hello, World', 0x0a
  3 length equal $-message
  4
  5 message 2 db 'Japan', 0x0a
  6 length 2equ$-message2

Now length represents only the 'Hello, World', 0x0a part

If you're going to learn from now on, I think 64-bit code is better, int0x80 is an old way to write, and I think it's better to learn how to write subroutines for the C convention as soon as possible.


2022-09-30 18:44

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.