Форум программистов, компьютерный форум, киберфорум
Assembler: Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
2 / 2 / 4
Регистрация: 19.05.2017
Сообщений: 95
NASM

Ошибка в программе сравнения двух чисел

03.02.2018, 21:45. Показов 4374. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Проблема в сравнении двух чисел-вывод в обоих случаях один
OS Linux Ubuntu x86 64

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
section .data 
    message1  db "RAW ",0xa   ;сообщение если равны
    ln1 equ $ -message1
 
    message2  db "NOT RAW",0xa ;сообщение если нет
    ln2 equ $ -message2
 
 
section .text
 
    global main
 
main:                         ;начало программы
    mov eax,20            ;первый регистр для сравнения
    mov ebx,20        ;второй регистр для сравнения
 
    cmp ebx,eax           ;сравнение
    je m1                 ;если равны
        
m1:     mov edx,ln1           ;вывод если равны
    mov ecx,message1
    mov ebx,1
    mov eax,4
    int 0x80
 
    jmp exit              ;переход на выход
 
 
m2: mov edx,ln2           ;вывод если не равны
    mov ecx,message2
    mov ebx,1
    mov eax,4
    int 0x80
    
    jmp exit              ;переход на выход
    
 
    
exit:   mov eax,1             ;выход
    int 0x80
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.02.2018, 21:45
Ответы с готовыми решениями:

Ошибка 113 в программе определения большего из двух чисел
program 5z; var a,b,c:integer; begin a:=2; b:=6; if a<b then writeln('A<B'); else ...

Ошибка в программе сравнения слов
Программка переписана из учебника и по ней есть несколько заданий, однако она не работает. #include"std_lib_facilities.h" можно...

Сравнения двух чисел
Подскажите как реализовать сравнение двух чисел.Например если А>=B то переход на метку1. Нашла комнаду CMP, а как ею воспользоваться не...

19
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8645 / 4480 / 1669
Регистрация: 01.02.2015
Сообщений: 13,888
Записей в блоге: 11
03.02.2018, 23:04
Проверьте логику перехода после сравнения (строку 18).

Добавлено через 1 минуту
Другими словами, на какую метку будет переход если условие выполнится и на какую если условие не выполнится?
0
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
09.02.2018, 12:58
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
section .data 
    message1  db "RAW ",0xa   ;сообщение если равны
    ln1 equ $ - message1
 
    message2  db "NOT RAW",0xa ;сообщение если нет
    ln2 equ $ - message2
 
section .text
 
global main
 
main:                         ;начало программы
    mov eax,20            ;первый регистр для сравнения
    mov ebx,20        ;второй регистр для сравнения
    
    cmp ebx,eax           ;сравнение
    je m1                 ;если равны
 
    mov edx,ln2           ;вывод если не равны
    mov ecx,message2
    mov ebx,1
    mov eax,4
    int 0x80
    
    jmp exit              ;переход на выход
 
m1:
    mov edx,ln1           ;вывод если равны
    mov ecx,message1
    mov ebx,1
    mov eax,4
    int 0x80
 
exit:
    mov eax,1             ;выход
    int 0x80
1
Заблокирован
09.02.2018, 13:21
nezabudka,
1.0xA - перевод на следующую строку, а не конец строки, здесь нужен
Assembler
1
message1  db "RAW ",0
2.скорее должно быть
Assembler
1
mov ecx,offset message2
или
Assembler
1
lea ecx,message2
3.
Assembler
1
2
3
4
5
6
7
8
9
10
   cmp ebx,eax           ;сравнение
    je m1                 ;если равны 
    mov edx,ln2           ;вывод если не равны
    mov ecx,offset message2      
    jmp m2              ;переход на выход 
m1: mov edx,ln1           ;вывод если равны
    mov ecx,offset message1
m2: mov ebx,1
    mov eax,4
    int 0x80
2
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
09.02.2018, 13:54
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    mov eax,20            ;первый регистр для сравнения
    mov ebx,20        ;второй регистр для сравнения
    
    cmp ebx,eax           ;сравнение
    je m1                 ;если равны
 
    mov edx,ln2           ;вывод если не равны
    mov ecx,message2
    jmp next
m1:
    mov edx,ln1           ;вывод если равны
    mov ecx,message1
 
next:   
    mov ebx,1
    mov eax,4
    int 0x80
 
    mov eax,1             ;выход
    int 0x80
2
Заблокирован
09.02.2018, 14:06
nezabudka,
работает или нет?
  • если NASM подобен FASM, тогда
    Assembler
    1
    2
    
    mov ecx,message2; в есх адрес message2
    mov ecx,[message2]; в есх четыре символа "N", "O", "T" и " "
  • если NASM подобен MASM, тогда
    Assembler
    1
    2
    
    mov ecx,offset message2; в есх адрес message2
    mov ecx,dword ptr message2; в есх четыре символа "N", "O", "T" и " "
1
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
09.02.2018, 18:53
Цитата Сообщение от Uncle Remus Посмотреть сообщение
работает или нет?
свой код обязательно проверяю, все работает именно так как выложено.
Единственное заменила global main на global _start и компилировала
Bash
1
2
nasm -f elf32 test.asm
ld -melf_i386 -s test.o -o test
У меня 64 бинтая система. С fasm сталкивалась, masm совершенно не знаком.
Стараюсь работать с gas, мне так удобней и с gdb и с преобразованием Си кода.
2
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6808 / 2048 / 238
Регистрация: 14.12.2014
Сообщений: 4,299
Записей в блоге: 12
09.02.2018, 22:37
Цитата Сообщение от Uncle Remus Посмотреть сообщение
2.скорее должно быть
Нет, это NASM.
mov ecx,N - это то же самое, что mov ecx,offset N в MASM (как в fasm, короче).

Добавлено через 3 минуты
Если система 64-битная, то и регистры надо использовать 64-битные.
К тому же, там вызов системных функций делается по-другому (и коды функций другие), никаких int 0x80:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
; mov rax,function_number
; mov rdi,param_1  ; if any
; mov rsi,param_2  ; if any
; mov rdx,param_3  ; if any
; mov r10,param_4  ; if any
; mov r8,param_5   ; if any
; mov r9,param_6   ; if any
; syscall  ; do it! (rcx and r11 will be destroyed)
 
%define __NR_read 0
%define __NR_write 1
%define __NR_exit 60
 
  mov rax,__NR_read
  mov rdi,1
  mov rsi,message
  mov rdx,ln2
  syscall
Добавлено через 3 минуты
Ну и компиляция:
Bash
1
2
nasm -f elf64 test.asm
ld -m elf_x86_64 -s test.o -o test
Добавлено через 56 секунд
Или надо просто 32-битный код запустить в x64 системе?

Добавлено через 8 минут
nezabudka, можно ещё упростить:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    mov eax,20            ;первый регистр для сравнения
    mov ebx,20        ;второй регистр для сравнения
    
    mov edx,ln1           ;вывод если равны
    mov ecx,message1
 
    cmp ebx,eax           ;сравнение
    je .eq                 ;если равны
 
    mov edx,ln2           ;вывод если не равны
    mov ecx,message2
 
.eq:
    mov ebx,1
    mov eax,4
    int 0x80
 
    mov eax,1             ;выход
    int 0x80
0
10.02.2018, 02:02

Не по теме:

Цитата Сообщение от nezabudka Посмотреть сообщение
У меня 64 бинтая система
на какой войне ранили твою систему!? :)

0
Заблокирован
10.02.2018, 03:51

Не по теме:

proc3nt,
ладно 64 бинтая система, а ведь могла быть и 64 убитая система

0
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
10.02.2018, 20:21

Не по теме:

Цитата Сообщение от proc3nt Посмотреть сообщение
на какой войне ранили твою систему!?
На войне под названием Klavaro vs Stamina



Добавлено через 12 часов 36 минут
Цитата Сообщение от Jin X Посмотреть сообщение
Если система 64-битная, то и регистры надо использовать 64-битные.
Инструкции все равно 32 битные, а значит нужно использовать длинные регистры
только для адресов. В 64-битном режиме все инструкции mov , записывающие
что-либо в младшую 32-битную часть регистра, обнуляют старшие 32-бита
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
section .data 
    message1  db "RAW ",0xa
    ln1 equ $ - message1
 
    message2  db "NOT RAW",0xa
    ln2 equ $ - message2
 
section .text
 
global _start
 
_start:
    mov eax,20
    mov ebx,20
    
    cmp ebx,eax
    je m1
 
    mov edx,ln2
    mov rsi,message2
    jmp next
m1:
    mov edx,ln1
    mov rsi,message1
 
next:   
    xor eax,eax
    inc eax
    mov edi,eax
    syscall
 
    mov eax,60
    xor edi,edi
    syscall
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6808 / 2048 / 238
Регистрация: 14.12.2014
Сообщений: 4,299
Записей в блоге: 12
10.02.2018, 20:34
Цитата Сообщение от nezabudka Посмотреть сообщение
Инструкции все равно 32 битные, а значит нужно использовать длинные регистры
только для адресов. В 64-битном режиме все инструкции mov , записывающие
что-либо в младшую 32-битную часть регистра, обнуляют старшие 32-бита
NASM (в отличие от fasm) сам оптимизирует mov rax,4 до mov eax,4, поэтому тут можно не заморачиваться
0
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
10.02.2018, 21:21
Jin X, Во загнула С размерами инструкций разбирается операционка, я имела в виду правильно
выбраную размерность данных.
Цитата Сообщение от Jin X Посмотреть сообщение
сам оптимизирует
Что то я об этом не подумала Сейчас посмотрю что
там асемблер gas выдает. Думаю даже al найду

Добавлено через 24 минуты
al не нашла но единичку и нолик пишет в 32 битный регистр
movl $1, %edi
movl $0, %eax


Добавлено через 7 минут
А вот вывод objdump -d предшествующей программы на nasm x86_64
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
00000000004000b0 <.text>:
  4000b0:   b8 14 00 00 00          mov    $0x14,%eax
  4000b5:   bb 14 00 00 00          mov    $0x14,%ebx
  4000ba:   39 c3                   cmp    %eax,%ebx
  4000bc:   74 11                   je     0x4000cf
  4000be:   ba 08 00 00 00          mov    $0x8,%edx
  4000c3:   48 be f5 00 60 00 00    movabs $0x6000f5,%rsi
  4000ca:   00 00 00 
  4000cd:   eb 0f                   jmp    0x4000de
  4000cf:   ba 05 00 00 00          mov    $0x5,%edx
  4000d4:   48 be f0 00 60 00 00    movabs $0x6000f0,%rsi
  4000db:   00 00 00 
  4000de:   31 c0                   xor    %eax,%eax
  4000e0:   ff c0                   inc    %eax
  4000e2:   89 c7                   mov    %eax,%edi
  4000e4:   0f 05                   syscall 
  4000e6:   b8 3c 00 00 00          mov    $0x3c,%eax
  4000eb:   31 ff                   xor    %edi,%edi
  4000ed:   0f 05                   syscall
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6808 / 2048 / 238
Регистрация: 14.12.2014
Сообщений: 4,299
Записей в блоге: 12
11.02.2018, 20:59
Цитата Сообщение от nezabudka Посмотреть сообщение
al не нашла
А что там могло быть с al?
0
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
12.02.2018, 22:13
Я и тут умудрилась накосячить. В 64 битной системе под линем программа
использует для адресации по умолчанию относительные пути, тоесть
адрес текущей инструкции который находится в регистре
%rip, и такой, относительный адрес в программе является 32 битным,
если не указать явно использовать 64 битный абсолютный
адресс командой movabs. И если не указывать абсолютный
адресс в программе то адресное пространство доступное
программе будет около 4Гигов, что вполне достаточно
для большинства программ без дополнительного усложнения.
Так что текущий адрес программы является как бы смещением
для 32 битных адресов используемых в 64 битной программе. А значит
можно переписать вот таким образом. Воспользуюсь более
привычным мне асемблером gas
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        .data 
msg1: .string "RAW\n"
ln1 = . - msg1
 
msg2: .string "NOT RAW\n"
ln2 = . - msg2
 
        .text
.globl _start
 
_start:
    mov $20, %al 
    mov $20, %bl 
    
    cmp %bl,%al
    je m1
 
    mov $ln2, %dl 
    mov $msg2, %esi
    jmp next
m1:
    mov $ln1, %dl 
    mov $msg1, %esi
 
next:   
    mov $1, %al 
    mov %al, %dil
    syscall
 
    mov $60, %al 
    mov $0, %dil
    syscall
Программа получилась на 24 байта меньше предыдущей
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6808 / 2048 / 238
Регистрация: 14.12.2014
Сообщений: 4,299
Записей в блоге: 12
12.02.2018, 22:36
Прикол только в том, что использование al вместо rax (или dil вместо rdi) не обнулит старшую часть регистра... в котором может быть мусор. Вывод сообщения требует во всём регистре rax (а не только в al) значения = 1. Это не работает так же, как с eax, когда при записи в eax старшая половина rax обнуляется. При записи в al старшие 56 бит rax не обнулятся (аналогично с dil/rdi и т.д.)
И даже если сейчас это работает, то потому, что просто повезло (в стершей части были нули) и не факт, что будет работать, если перенести этот код в другое место. Так что, так делать не советую.

Добавлено через 8 минут
И 64-битная программа вполне может использовать более 4 Гб памяти. Просто это будет область динамической памяти, где работа идёт через указатели, которые могут хранить в себе любое 64-битное значение. Обычные переменные будут находиться в пределах 4 Гб (даже 2 Гб, т.к. это значение знаковое... сложно себе представить программу, где нужно больше, но это тоже можно сделать, если очень надо), т.к. обращение к ним идёт через указание конкретного (абсолютного) адреса (который кодируется внутри инструкции уже относительно rip): например, mov rax,[140002000h]. Для динамической памяти обращение будет через указатели:
Assembler
1
2
mov eax,[140002000h]  ; загружаем указатель (в котором вполне может быть смещение > 2 Гб)
mov eax,[eax]  ; получаем значение
1
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
12.02.2018, 23:09
Цитата Сообщение от Jin X Посмотреть сообщение
Прикол только в том, что использование al вместо rax (или dil вместо rdi) не обнулит старшую часть регистра.
Да, это так. Я пробовала в %ah записать число и последующая запись в %al не обнулила старшие биты.
Еще думаю что на выравнивании можно больше проиграть
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6808 / 2048 / 238
Регистрация: 14.12.2014
Сообщений: 4,299
Записей в блоге: 12
13.02.2018, 14:14
Цитата Сообщение от nezabudka Посмотреть сообщение
Еще думаю что на выравнивании можно больше проиграть
На выравнивании чего? И в какой целью играть хотите?

Добавлено через 55 секунд
Цитата Сообщение от Jin X Посмотреть сообщение
mov eax,[140002000h] ; загружаем указатель (в котором вполне может быть смещение > 2 Гб)
mov eax,[eax] ; получаем значение
rax тут должен быть, чего это я?

Добавлено через 22 минуты
Цитата Сообщение от nezabudka Посмотреть сообщение
Я пробовала в %ah записать число и последующая запись в %al не обнулила старшие биты.
Автоматом обнуляет старшие биты только запись (в т.ч. изменение: add, sbb, or, mul reg32 и т.д.) в 32-битный регистр (eax, edx...) в режиме x64. Если хотите сэкономить байты кода, то можно сделать так, как вы уже делали раньше:
Assembler
1
2
xor eax,eax
inc eax  ; экономия за счёт небольшого проигрыша в скорости
Ну и всякие там:
Assembler
1
2
xor eax,eax
mov al,5
Assembler
1
or rax,-1  ; запись -1
Assembler
1
and [rax],0  ; запись 0 в память (но работает медленнее)
Assembler
1
or [rax],-1  ; запись -1 в память (но работает медленнее)
и т.д...

Но, откровенно говоря, в современных реалиях гнаться за сохранением объёма кода в ущерб производительности (я про 2 последних варианта, по крайней мере) не имеет особого смысла (если только вы не пишете демку какую-нибудь). Скорость будет актуальна всегда (для некоторых задач, разумеется... во многих случаях всё же вполне и Python или Java сгодятся), а о размере можно особо не париться, если только не доводить дело до абсурда (например, когда пустой проект Delphi 10.2 с VCL-формой весит 2 мега - release, а не debug(!) или когда 1 поток в Java отжирает по пол-Мб памяти).
1
Заблокирован
24.03.2018, 12:22
Цитата Сообщение от nezabudka Посмотреть сообщение
Да, это так. Я пробовала в %ah записать число и последующая запись в %al не обнулила старшие биты.
Хех, а для чего б тогда нам были нужны mozx?
0
Эксперт NIX
 Аватар для nezabudka
3334 / 752 / 252
Регистрация: 28.06.2015
Сообщений: 1,552
Записей в блоге: 16
24.03.2018, 17:04
Цитата Сообщение от Pavel_Srgv Посмотреть сообщение
mozx?
movzx
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.03.2018, 17:04
Помогаю со студенческими работами здесь

Функция сравнения двух чисел
Проверьте кто-нибудь код пожалуйста. Задача : Написать программу, выводящую на экран результат сравнения двух чисел в виде: A=10 B=5:...

Схема сравнения двух четырехразрядных чисел
вот схема для сравнения больше. помогите мне что нужно изменить для схемы меньше

Напишите функцию сравнения двух чисел
Напишите функцию, которая принимает два целых числа, и определяет большее из них.

Программа для сравнения двух чисел
a=6//// ввод первого числа b=4///// ввод второго числа c=a-b//// разность if c&gt;0 then disp a&gt;b//// условия elseif c=0 then disp...

Длинная арифметика: операция сравнения двух чисел (A >= B)
Привет всем! помогите пожалуйста кодом. Необходимо реализовать операцию сравнения двух длинных чисел A&gt;=B Заранее спасибо


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод Сайт называется reddit: The Thinkpad X220 Tablet is the best budget school laptop period. Это. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru