Большое спасибо! Комментарии были полезны, помогли мне научиться, а не просто копировать.

я набираю ld -m elf_i386 -o loop loop.asm, я получаю ошибку, указанную в заголовке, есть идеи, что ее вызывает? Извините, если код выглядит плохо, довольно новый для сборки.

cr equ 13 
lf equ 10 

section .bss
numA resb 1

section .text

global _start:

mov [numA],byte 0
call loop1
jmp endend
loop1:
xor cx,cx
mov al, $numA
cmp cx, 0x0A
jle else 
inc al
jmp end
else:
dec al
jmp end
end:
mov [$numA], al
inc cx
cmp cx,20
jle loop1

endend:
mov dl,$numA
mov ah,2
int 21h
 Ped7g25 окт. 2017 г., 11:36
Я попытался скомпилировать ваш исходный код, и у него есть реальные семантические / синтаксические проблемы, некоторые вещи не имеют особого смысла в сборке x86-32. Я постараюсь угадать, чего вы хотели добиться, и выложу фиксированный источник. ... Я в некотором роде смущен тем, что вы подразумеваете под$numAзачем знак доллара там? Я еще не видел, чтобы в источнике NASM автономный доллар был текущим адресом инструкции, поэтому что-то вроде$-numA будет что-то значить для меня, но$numA мне неизвестно.
 malik aasen25 окт. 2017 г., 11:35
Опечатка, означает loop.o, команда nasm: nasm -f elf -F dwarf -g loop.asm
 malik aasen25 окт. 2017 г., 11:41
Я нашел в Интернете некоторый код о том, как получить циклы и тому подобное, пытаясь изучить ассемблер. программа просто запускает цикл и добавляет 1 к numa, если цикл <10, и уменьшает его, если цикл равен>> 10.
 Ped7g25 окт. 2017 г., 11:30
Вы уверены, что вводите.asm подать вld? Я не думаю, что это может работать, ты имел в виду.o? Тогда покажи такжеnasm Команда, как вы собираете.asm в.o, Вы, вероятно, компилируете asm в объектный файл 64b. Чтобы получить полную цепочку двоичных файлов 32b nasm-> ld->, которую я использую в * buntu:nasm -w+all test.asm -l test.lst -f elf32 ld -m elf_i386 test.o -o test (заtest.asm) (если это так, то это дубликат одного из многих вопросов "как компилировать 32b asm в 64b linux")
 Ped7g25 окт. 2017 г., 11:40
«Идентификатору также может предшествовать $, чтобы указать, что он предназначен для чтения в качестве идентификатора, а не зарезервированного слова» издокументы ... Жаль, что я забуду это, так как я вместо этого никогда не использую зарезервированные слова для идентификаторов, отличная особенность.

Ответы на вопрос(2)

Решение Вопроса

$numA такой же какnumA. Ведущий$ мешает ассемблеру рассматривать его как имя регистра, Таким образом, вы можете написатьmov eax, [$eax] загрузитьeax зарегистрироваться из символа под названиемeax, (Так что вы можете связать с C, который использовалint eax = 123;)

Такmov [$numA], al выглядит странно, но это действительно простоmov [numA], al и не является источником предупреждения.

Вы получаете предупреждение отmov dl,$numA который делаетmov dl, imm8 младшего байта адреса.

Компоновщик предупреждает вас, потому что адресnumA не помещается в 1 байт, поэтомуr_386_8 Переезд усеченный адрес.

_8 говорит вам, что это перемещение, которое просит компоновщик заполнить 8 бит.r_386 говорит вам, что это перемещение i386 в отличие от какого-то типаr_x86_64 перемещение (которое может быть абсолютным или относительным к RIP), или перемещение цели перехода MIPS (которое должно было бы сместить вправо смещение на 2). Возможно связано:Переезды в Системе V ГАБИ (универсальный ABI, для которого i386 SysV psABI является «дополнением к процессору»).

 malik aasen25 окт. 2017 г., 12:01
Спасибо, исправили это! Быстрый вопрос, endend используется для печати numa, мне нужно преобразовать его в ascii / наоборот?
 Ped7g25 окт. 2017 г., 12:20
@malikaasen да, нет DOS илисистема Linux вызов для вывода целочисленного значения. В DOS вы можете вывести хотя бы один расширенный 8-символьный ASCII-символ в Linux, насколько мне известноsys_write доступен, который принимает в качестве входных данных только блок байтов, хранящихся в памяти.
 Peter Cordes25 окт. 2017 г., 12:30
@malikaasen: Вы можете связаться с libc и заставить printf сделать это за вас. Или вы можете преобразовать цифры в строку самостоятельно и распечатать это. (См. Раздел часто задаваемых вопросов о многозначном номере вstackoverflow.com/tags/x86/info). Кстати, у вас естьint 21h в вашем коде, но вы делаете исполняемый файл ELF. Linux не реализует DOSint 21h Системный вызов ABI / API вообще. Видетьstackoverflow.com/questions/2535989/....

;* о том, что я изменил:

;* build commands used to test:
;* nasm -f elf32 -F dwarf -g loop.asm -l loop.lst -w+all
;* ld -m elf_i386 -o loop loop.o

cr equ 13
lf equ 10

section .bss
numA resb 1

section .text

global _start   ;* global directive takes symbol name (without colon)

_start:
;* the actual label you defined as global, and want to start from.

    ;* set memory at numA address to byte zero
    mov [numA],byte 0
    ;* try to call subroutine with loop
    call loop1
    jmp endend

loop1:
    xor cx,cx       ;* loop counter = 0
.real_loop: 
;* you don't want to loop to "loop1" as that will reset CX!
    mov al, [$numA] ; load AL with value from memory at numA address
;* in NASM you must use [] to indicate memory load/store
;* the mov al, $numA tried to put the memory address numA into AL
;* but memory address in x86-32 is 32 bit value, and AL is 8 bit only
;* and you didn't want address, but value any way.
    cmp cx, 0x0A
    jle .else 
    inc al
    jmp .end
.else:
;* I modified all subroutine labels to be "local" starting with dot
;* i.e. ".else" is full label "loop1.else". This practice will allow
;* you to use also ".else" in different subroutines, while global
;* "else:" can be used only once per source file.
    dec al
    jmp .end
.end:
    mov [$numA], al
    inc cx
    cmp cx,20
    jle .real_loop      ;* fix of loop jump (to not reset CX)
    ;* after CX will reach value 21, the CPU will continue here
    ret         ;* so added return from subroutine

endend:
    ;* call linux 32b sys_exit(numA value) to terminate
    ;* return value will be equal to zero-extended [numA] to 32bits
    ;* 8bit -1 = 0xFF -> return value is 255
    movzx   ebx,byte [$numA]
    mov     eax,1
    int     80h

После запуска этого:

nasm -f elf32 -F dwarf -g loop.asm -l loop.lst -w+all
ld -m elf_i386 -o loop loop.o
./loop ; echo $?

Ожидается выход:

255
 malik aasen25 окт. 2017 г., 12:36
Большое спасибо! Комментарии были полезны, помогли мне научиться, а не просто копировать.

Ваш ответ на вопрос