Игорь Пашев

Jul. 14th, 2011

08:34 pm - НОД на ассемблере (x86, 32 бита, Солярис 11)

https://github.com/ip1981/GCD/blob/master/assembler/gcd-x86-solaris.s

По системным вызовам Соляриса:
http://my.opera.com/myrkraverk/blog/2010/02/02/directly-calling-solaris-system-calls

Различия с линуксовой версией:

--- gcd-x86-linux.s	2011-07-04 00:33:43.000000000 +0400
+++ gcd-x86-solaris.s	2011-07-14 20:31:09.000000000 +0400
@@ -68,12 +68,15 @@
     
     # printing the number:
     mov $4,   %eax # syscall `write'
-    mov $1,   %ebx # write to stdout
-    mov %edi, %ecx # first character to write
     mov $buf_end, %edx
     sub %edi, %edx # edx is a number of characters to write (buf_end - edi)
     inc %edx       # + new line
-    int $0x80      # do syscall (print the number)
+    push %edx
+    push %edi # first character to write
+    push $1   # write to stdout
+    push $0   # dummy
+    int $0x91 # do syscall (print the number)
+    add $16, %esp # clean stack 16 = 4 * 4 (32 bits!)
 
     ret
 
@@ -133,6 +136,7 @@
 
 exit:
     mov $1,   %eax  # exit syscall
-    xor %ebx, %ebx  # exit code = 0
-    int $0x80
+    push $0       # exit code = 0
+    push $0       # dummy
+    int $0x91
 

Tags: , , ,
(Оставить комментарий)

Jul. 4th, 2011

12:39 am - НОД на ассемблере (x86, 32 бита, линукс)

https://github.com/ip1981/GCD/blob/master/assembler/gcd-x86-linux.s

Невероятный по красоте способ перевода строки в целое число
(http://www.cyberforum.ru/archive/t-214807.html):

str2uint_loop:
    lodsb # going forward from esi
    # HINT: assert '0' <= al <= '9'
    lea    (%ebx, %ebx, 4), %ebx # ebx = 4*ebx + ebx = 5*ebx ;-)
    lea -48(%eax, %ebx, 2), %ebx # ebx = 2*ebx + %eax - 48
                                 # ebx is multiplied by 10 each iteration,
                                 # eax-48 will be multiplied at the next iteration ;-)
    loop str2uint_loop
    ret


Алсо поупражнялся с GDB.
Алсо в планах Солярка и 64 бита.

Tags: , , ,
(Оставить комментарий)

Nov. 29th, 2010

11:18 pm

gcc заменяет printf с простой строкой на puts.

С -O2 выкидывает куски кода внутри 100%-ложных условий (if (0) {...}).

Круто, чо :-)

test.c:

#include <stdlib.h>
#include <stdio.h>

const int DEBUG = 0;

int main ( int argc, char *argv[] )
{
    if (DEBUG) {
        printf("Debug!\n");
    }
    return EXIT_SUCCESS;
}



gcc -save-temps test.c -o test:
    .file	"test.c"
.globl DEBUG
	.section	.rodata
	.align 4
	.type	DEBUG, @object
	.size	DEBUG, 4
DEBUG:
	.zero	4
.LC0:
	.string	"Debug!"
	.text
.globl main
	.type	main, @function
main:
	leal	4(%esp), %ecx
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ecx
	subl	$4, %esp
	movl	DEBUG, %eax
	testl	%eax, %eax
	je	.L2
	subl	$12, %esp
	pushl	$.LC0
	call	puts
	addl	$16, %esp
.L2:
	movl	$0, %eax
	movl	-4(%ebp), %ecx
	leave
	leal	-4(%ecx), %esp
	ret
	.size	main, .-main
	.ident	"GCC: (GNU) 4.4.4"
	.section	.note.GNU-stack,"",@progbits

gcc -O2 -save-temps test.c -o test:
	.file	"test.c"
	.text
	.p2align 4,,15
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	xorl	%eax, %eax
	popl	%ebp
	ret
	.size	main, .-main
.globl DEBUG
	.section	.rodata
	.align 4
	.type	DEBUG, @object
	.size	DEBUG, 4
DEBUG:
	.zero	4
	.ident	"GCC: (GNU) 4.4.4"
	.section	.note.GNU-stack,"",@progbits

Tags: , , ,
(3 комментария | Оставить комментарий)

Nov. 17th, 2010

09:40 pm

Чтоб не забыть: минимальная программа на ассемблере,
выводящая "Hello!" (без glibc)

.data

msg:
    .string "Hello!\n"
    .set length, . - msg - 1

.text
.globl _start

_start:
    movl    $4, %eax
    movl    $1, %ebx
    movl    $msg, %ecx
    movl    $length, %edx
    int     $0x80

    movl    $1, %eax
    xorl    %ebx, %ebx
    int     $0x80


Компилировать так:
gcc -nostdlib hello.s -o hello
Размер — 623 байта.

Подробности тут http://ru.wikibooks.org/wiki/Ассемблер_в_Linux_для_программистов_C

Tags: , ,
(5 комментариев | Оставить комментарий)