start:
....
mov sp, start + 512 + 1024
org 0x7c00
start:
mov ax, 0
mov ss, ax
mov sp, start + 512 + 1024
mov ax, 0x060 ;(1024+512)/16=96=60h адрес стека после загрузчика в сегментах mov ss, ax ;установка адреса сегмента стека mov sp, 1024 ;установка указателя стека
add ax, 0x060 ;адрес стека после загрузчика в сегментах 0x07C0+0x060
На ассемблере в программе есть раздел .text, .bss, .data
при компиляции в машинный код там тоже так на сегменты разбит
для выполнения процессором
mul al,5
idiv cx,4
sar cx, 2
mov al,x cmp al,a jg sled1 mov bl,a ...
как сделать разветвление от условия, если это условие не удовлетворяет.
jg sled1
не совершает перехода и ты просто выполняешь следующую за ней инструкцию -- mov bl, a
. Ветвления и переходы в твоём коде выглядят правильно. RSP: 0x00007FFFFFFFEA78
) указывает примерно в то же место, где находится код программы (0x7fffffffea75: push rbx
). Код обычно защищён от записи, соответственно записать в стек может быть нельзя по этой причине. Кроме того, если записать в стек таки можно, push rbx как раз перепишет саму себя и следующую инструкцию. Без отладчика это может работать за счёт конвейера, но под отладчиком это работать не будет. Правильный ли ход мыслей?
только проблема в том, что в gcc формат ассемблерных вставок другой
int main() {
int a = 1;
int b = 3;
int c;
asm (
"mov %[a], %[c]\n\t"
"add %[b], %[c]\n\t"
: [c] "=mr" (c)
: [a] "mr" (a), [b] "mr" (b));
printf("a + b = %x + %x = %x\n", a, b, c);
}
Меня напрягает вечное указание размера функции
Можно ли это как-то убрать, и просто объявлять: _MessageBox, _ExitProcess, как с msvcrt: _printf, __getch и т.д?
$ gcc -nostartfiles -static str.s -o str
$ gdb ./str
...
(gdb) b *0x40102f
Breakpoint 1 at 0x40102f
(gdb) r
Starting program: /home/jcmvbkbc/tmp/toster/str
Breakpoint 1, 0x000000000040102f in _start ()
(gdb) x/3b $rsi - 3
0x402000 <source>: 1 2 3
(gdb) x/3b $rdi - 3
0x402010 <dest>: 1 2 3
Почему не работает
leaw arrayW, %si movw (%si), %ax
leal arrayW, %esi
movw (%esi), %ax
$ gcc -m32 -static -nostartfiles load.s -o load
$ gdb ./load
(gdb) b _start
Breakpoint 1 at 0x8049000
(gdb) r
Starting program: /home/jcmvbkbc/tmp/toster/load
Breakpoint 1, 0x08049000 in _start ()
(gdb) si
0x08049006 in _start ()
(gdb)
0x08049009 in _start ()
(gdb) p/x $esi
$1 = 0x804a000
(gdb) p/x $ax
$2 = 0x5
Для чего развивают GNU Assembler
GAS практически не документирован
синтаксис не тот, не зажигает он меня.
получается какой-то высокоуровневый код, который меня не привлекает.
Как объявить процедуру с аргументом строкой?
proc getel text
endp
signed __int8 numerator = 0; signed __int16 denominator = 0;
extern numerator:sword extern denominator:sbyte ... mov denominator, al
__int8 numerator
на __int16 numerator
, extern denominator:sbyte
на extern denominator:sword
а mov denominator, al
на mov denominator, ax
, чтобы стало как надо.include 'linInclude/proc64.inc'
format ELF64 executable 3
include '/usr/share/fasm/examples/elfexe/dynamic/import64.inc'
interpreter '/lib64/ld-linux-x86-64.so.2'
needed 'libc.so.6'
import exit, printf
segment readable executable
entry $
lea rdi, [fmtS]
lea rsi, [msg]
call [printf]
call [exit]
segment readable writeable
msg db 'Hello, World!', 0xA, 0
fmtS db '%s', 0xA, 0